浅拷贝和深拷贝
浅拷贝
创建一个对象,这个对象有着对原始对象属性的值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型, 拷贝的就是内存地址,所以其中一个对象改变会影响另外一个对象。
深拷贝
深拷贝会拷贝所有属性,并拷贝属性指向的动态分配内存,当对象和它所引用的对象一起拷贝时即发生深拷贝。
实现一个 Object.assign 大致思路如下:
1、判断原生 Object 是否支持该函数,如果不存在的话创建一个函数 assign,并使用 Object.defineProperty 将该函数绑定到 Object 上。
2、判断参数是否正确(目标对象不能为空,我们可以直接设置{}传递进去,但必须设置值)。
3、使用 Object() 转成对象,并保存为 to,最后返回这个对象 to。
4、使用 for..in 循环遍历出所有可枚举的自有属性。并复制给新的目标对象(使用 hasOwnProperty 获取自有属性,即非原型链上的属性)。
if (typeof Object.assign2 !='function') {
Object.defineProperty(Object, 'assign2', {
value:function (target) {
if (target == null) {
throw new TypeError('Cannot convert undefined or null to object');
}
let to = Object(target)
for (let index =1; index < arguments.length; index++) {
let nextSource = arguments[index];
if (nextSource !=null) {
for (let nextKeyin nextSource) {
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey]
}
}
}
}
return to
},
writable:true,
configurable:true
})
}
深拷贝可以拆分成2步, 浅拷贝+递归,浅拷贝时判断属性值是否为对象,如果是就进行递归操作。
function cloneDeep(source) {
if (!isObject(source))return source; // 非对象返回自身
var target = Array.isArray(source) ? [] : {};
for(var keyin source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
if (isObject(source[key])) {
target[key] =cloneDeep(source[key]); // 注意这里
}else {
target[key] = source[key];
}
}
}
return target;
}
function isObject(obj) {
return typeof obj ==='object' && obj !=null;
}