zl程序教程

您现在的位置是:首页 >  前端

当前栏目

javascript之深浅拷贝

JavaScript 拷贝 深浅
2023-09-11 14:21:46 时间

浅拷贝:

浅拷贝只拷贝基本类型的数据,而符合类型的数据只复制指向其的指针,而不复制对象本身,新旧对象还是共享同一块内存。

深拷贝:

深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

浅拷贝的实例:

/**
 * 浅拷贝
 *
 * @param {Object} target 目标对象
 * @param {Object} source 源对象
 * @return {Object} 返回目标对象
 */
function extend(target, source) {
    for (var key in source) {
        if (source.hasOwnProperty(key)) {
            var value = source[key];
            if (typeof value !== 'undefined') {
                target[key] = value;
            }
        }
    }

    return target;
}

测试一下:

var obj={
	a:1,
	b:2,
	c:{
		c1:'456',
		c2:'789'
	}
}
var o={};
extend(o,obj)
console.log(o)

可以看到确实将obj的属性都copy了,我们来测试一下符合类型的,在控制台修改一下obj.c.c1里面的值,来看一下新对象o有什么表现:

从中我们可以了解到,修改了原对象的复合类型属性,会影响到新对象的属性,因为针对复合类型并不是真正意义上的copy,只是拿过来了引用地址。

再来看看深拷贝:

	var class2type={};	//定义一个对象
	var typeArr = "Boolean Number String Function Array Date RegExp Object".split(" ");//将所有的类型放到一个数组
	for(var i=0,len=typeArr.length;i<len;i++){
		var name=typeArr[i];
		class2type[ "[object " + name + "]" ] = name;
	}
	 
	function getType( obj ) {
		return obj == null ?
			String( obj ) :
			class2type[ Object.prototype.toString.call(obj) ] || "undefined";
	}

   function deepCopy(obj) {
	    var result, oClass = getType(obj), copy;
	    if (oClass == "Object") 
	    	result = {}; //判断传入的如果是对象,继续遍历
	    else if (oClass == "Array") 
	    	result = []; //判断传入的如果是数组,继续遍历
	    else 
	    	return obj; //如果是基本数据类型就直接返回
	
	    for (var key in obj) {
	    	if(obj.hasOwnProperty(key)){
		        copy = obj[key];
				if(copy===null){
					break;
				}
				if(typeof copy ==='undefined'){
					result[key]=undefined;
				}else if (getType(copy) == "Object"||getType(copy) == "Array") 
					result[key] = deepCopy(copy); //递归方法
		        else 
		        	result[key] = copy; //基本数据类型则赋值给属性
	        }
	    }
	    return result;
	}

上面用到了判断数据类型的方法,在之前的文章中有讲过,这里就拿来直接用了,测试一下:

var o = deepCopy(obj);
console.log(o)

看输出,并修改一下obj的复合属性,看新对象是何表现:

对象正常copy了,下面来修改一下原对象obj的相关属性,看结果:

原对象的复合属性c下面的c1被修改成了007,再看看新对象o

发现新对象o下面的c的c1属性并并没有收到影响,还是456 ,新旧对象互相不影响,这就是深copy达到的效果。

另外:JSON 对象的 parse 和 stringify都是深拷贝,这个使用起来也很方便哇!