`

js对象的克隆

阅读更多

      由于js是采用引用传值的,故修改任何一个对象,其关联的对象也会被改变,但很多时候我们只想得到一个对象的拷贝,而非引用。下面提供了一种实现。不过除非程序中需要,否则要避免操作对象的拷贝,因为这样会影响性能,造成太多的递归调用(too much recursive)。

 

function clone(o) {
	if (!o) {
		return o;
	} else {
		var c;
		if (Object.prototype.toString.apply(o) === '[object Array]') {
			c = [];
			for (var i = 0; i < o.length; i++) {
				c.push(clone(o[i]));
			}
                 // 采用这种判断,而非typeof(o) === 'object',这里只处理Object,而不处理其他包括Array、String、Date、Function等,但由new创建的Function对象的也是Object
                 } else if (Object.prototype.toString.call(o) === '[object Object]') {
			c = {};
			for (var p in o) {
				c[p] = clone(o[p]);
			}
		} else {
			return o;
		}
                return c;
        }
}

      该方法当对象中有大量的数据时,进行深拷贝会进行大量的递归,这样可能会造成程序不能运行下去,所以尽量避免使用。如果必须使用时首先得确保被拷贝的对象不是很大。

 

      另外对于数组,如果数组中的元素是数字型或是字符型的,可以调用concat来简单的完成数组的复制

 

var arr1 = [12,34,56];
var arr3 = [].concat(arr1);
arr1.push(77);//arr1改变
alert(arr1);//12,34,56,77
alert(arr3);//12,34,56说明arr1和arr3不是指向同一个对象

var arr2 = [23,45,67];
arr3 = [].concat(arr1,arr2);//多个数组的复制
alert(arr1);
alert(arr2);
alert(arr3);
     通过运行以上代码,可以看出调用concat后,重新创建了一个对象。这里需要注意的,对于从正被连接到新数组的数组中复制的是对象参数,复制后仍然指向相同的对象。不论新数组和源数组中哪一个有改变,都将引起另一个的改变。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics