Q008:深拷贝/浅拷贝 深克隆/浅克隆

对象的拷贝方法

ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置。而引用类型值是指那些保存堆内存中的对象,意思是变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,该位置保存对象。
目前基本类型有:
Boolean、Null、Undefined、Number、String、Symbol,引用类型有:Object、Array、Function。之所以说“目前”,因为Symbol就是ES6才出来的,之后也可能会有新的类型出来。
深拷贝与浅拷贝的概念只存在于引用类型。

var copyObj={
	name:'lena',
	arr:[1,2,3]
}
var targetObj=JSON.parse(JSON.stringify(copyObj))
		此时就实现了深拷贝。

其实JQ里已经有$.extend()函数,实现就是深拷贝和浅拷贝的功能。
利用window.JSON的方法做深拷贝存在2个缺点:
如果你的对象里有函数,函数无法被拷贝下来
无法拷贝copyObj对象原型链上的属性和方法

浅拷贝
2个obj经过拷贝后,虽然他们属性相同,也的确是不同的对象,但他们内部的obj都是指向同一个内存空间。
深拷贝
调用deepCopy()后, 2个obj经过拷贝后,除了拷贝下来相同的属性之外,没有任何其他关联,而且obj2.arr和obj1.arr是指向不同的内存空间。

浅拷贝比较简单,就是用for in 循环赋值

unction shallowCopy(source, target = {}) {
        var key;
        for (key in source) {
            if (source.hasOwnProperty(key)) {        // 意思就是__proto__上面的属性,我不拷贝
                target[key] = source[key];
            }
        }
        return target;
    }

深拷贝的实现
深拷贝,就是遍历那个被拷贝的对象
判断对象里每一项的数据类型
如果不是对象类型,就直接赋值,如果是对象类型,就再次调用deepCopy,递归的去赋值。

function deepCopy( source ) {
    let target = Array.isArray( source ) ? [] : {}
    for ( var k in source ) {
        if ( typeof source[ k ] === 'object' ) {
            target[ k ] = deepCopy( source[ k ] )
        } else {
            target[ k ] = source[ k ]
        }
    }
    return target
}

以上的无论深、浅拷贝,都用了source.hasOwnProperty(key),意思是判断这一项是否是其自有属性,是的话才拷贝,不是就不拷贝。

原文链接:https://segmentfault.com/a/1190000012828382
参考文章:https://www.simbawu.com/article/search/9

克隆:

$().clone() 浅克隆: 仅克隆属性和样式,不克隆行为
$().clone(true) 深克隆: 即克隆属性和样式,又克隆行为

你可能感兴趣的:(面试问题)