var num1 = 123;var num2 = num1; // 这里内存中数据123有两个副本,因此是拷贝var obj1 = { name: 'jim' };var obj2 = obj1; //这里内存中数据只有一个,没有拷贝,因此这不是拷贝(2)深拷贝拷贝对象的所有数据,两个数据副本在内存中完全独立,就是深拷贝(3)浅拷贝(相对复杂些)拷贝的对象不完全,数据副本在内存中还有关联,就是浅拷贝(4)理解深浅拷贝深浅拷贝只有在对象含有引用类型的成员时才考虑。function Person( name ) { this.name = name; this.copy = function () { var tmp = new Person( this.name ); return tmp; }}var p1 = new Person( '张三' );var p2 = p1.copy();// 这里没有深浅拷贝之分浅拷贝:// 浅拷贝function Person( name ) { this.name = name; this.car = null; this.shallowCopy = function () { var tmp = new Person(); //拷贝出来的副本 for( var k in this ) { tmp[ k ] = this[ k ]; // 如果是值类型, 就直接拷贝了, 如果是引用类型, 就没有拷贝 } return tmp; };}function Car ( name ) { this.name = name;} var p1 = new Person( '李四' );p1.car = new Car( '劳斯莱斯' );var p2 = p1.shallowCopy();深拷贝:// 深拷贝// 1> 首先有一个函数, 该函数的特点是 深拷贝一个对象, 并将对象的拷贝结果返回// 2> 在函数内部实现算法, 首先准备一个对象// 3> 遍历目标对象中的所有属性// 4> 判断属性是否为值类型, 如果是值类型直接赋值// 5> 如果是引用类型:// -> 再准备一个对象// -> 再遍历这个属性// -> ...// => 如果是引用类型的对象, 就调用一次自己这个方法function deepCopyHandler( obj ) { // 深拷贝 obj 返回新对象 var tmp = {}; for ( var k in obj ) { if ( typeof obj[ k ] == 'object' ) { // 深拷贝 obj[ k ],递归 tmp[ k ] = deepCopyHandler( obj[ k ] ); } else { tmp[ k ] = obj[ k ]; } } return tmp;}function Person( name ) { this.name = name; this.car = null; this.deepCopy = function () { return deepCopyHandler( this ); }; }function Car ( name ) { this.name = name;} var p1 = new Person( '李四' );p1.car = new Car( '劳斯莱斯' );var p2 = p1.deepCopy();(5)例:为了兼容ie8,使用递归的方法实现 getElementsByClassName方法/** * 递归查找有指定类名的元素(进阶方法) * * 可以不新建空数组,也不返回,而将空数组作为参数传入函数 * 且在一开始就限定必须传数组,否则就抛出异常 * 这样的好处是,省去了拼接数组的过程,因为传入的一直是同一个数组 * * @param className 指定类名 * @param tag 总元素 * @returns {Array} */function getByClass(className,arr,tag){ if(typeof arr == 'undefined' || typeof arr.push != 'function'){ throw new Error('传入参数不正确!'); } tag = tag || document;//没传tag就用document元素 var nodes = tag.childNodes;//总元素下的所有子节点 /*遍历*/ for(var i=0; i<nodes.length; i++){ //找到元素节点 if(nodes[i].nodeType == 1){ //找到有类名且包含指定类名的元素 if(nodes[i].className && (' '+nodes[i].className+' ').indexOf(' '+className+' ') > -1){ arr.push(nodes[i]);//推进数组里 } //递归,接着查下一层子元素,找到就推进数组中 getByClass(className,arr,nodes[i]); } }}//使用该方法var divs = [];getByClass('c',divs);//该函数没有返回值,只能执行后从参数中得到结果alert(divs.length);for(var i=0; i<divs.length; i++){ divs[i].style.borderColor = 'green';}(6)扩展:深度拷贝对象时,类型不重要,方法是重要的函数,就是应该共享遍历的时候应该只考虑当前对象的成员,不考虑原型中的成员(用object.PRototype中提供的hasOwnProperty来判断)如果是数组或伪数组,最好不要一开始就创建{},而是创建[]较好
新闻热点
疑难解答