展开语法和Object.assign合并对象

296 阅读1分钟

Object.assign 方法只会拷贝源对象自身属性(不复制继承属性),也不复制不可枚举的属性(enumerable: false)。该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。

Object.assign() 函数会触发 setters,而展开语法则不会。

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// 克隆后的对象: { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
console.log(obj1); // { foo: 'bar', x: 42 };
console.log(mergedObj); //  { foo: "baz", x: 42, y: 13 }



const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };

const obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。

扩展运算符和Object.assign是深拷贝还是浅拷贝

扩展运算符

// 对象只有一级数据,是深拷贝
var obj1 = { foo: 'bar', x: 42 };
var clonedObj = { ...obj1 };
//console.log(clonedObj); // 克隆后的对象: { foo: "bar", x: 42 }
clonedObj.x = 30;
console.log(clonedObj);  // { foo: "bar", x: 30 }
console.log(obj1); // { foo: "bar", x: 42 }
// 对象有两层数据及以上,是浅拷贝
var obj2 = {    
    foo: 'baz',    
    y: 13 ,    
    su: {        
        name: 'mars'    
    }
};
var clonedObj = { ...obj2 };
clonedObj.su.name = 'kyire';
console.log(clonedObj);
console.log(obj2);
// 打印出的obj2和cloneObj都一样
{    
    foo: 'baz',    
    y: 13 ,    
    su: {        
        name: 'kyire'    
    }
}

Object.assign

对象只有一层数据,是深拷贝。两层及以上是浅拷贝

var obj2 = {    
    foo: 'baz',    
    y: 13 ,    
    su: {        
        name: 'mars'    
    }
};
var clonedObj = Object.assign({}, obj2);
clonedObj.y = 89;
clonedObj.su.name = 'kyire';
console.log(clonedObj);
{    
    foo: 'baz',    
    y: 89 ,    
    su: {        
        name: 'kyire'    
    }
}
console.log(obj2);
{    
    foo: 'baz',    
    y: 13 ,    
    su: {        
        name: 'kyire'    
    }
}

性能比对

Object.assign对象拷贝时速度更快

function testObject(){    
    let result = {};    
    console.time('A');    
    for(let i=0;i<2000;i++){        
        result = {...result, ['key' + i]: i };    
    }    
    console.timeEnd('A');
}
testObject();
// A: 555.3701171875 ms


function testObject(){    
    let result = {};    
    console.time('A');    
    for(let i=0;i<2000;i++){        
        result = Object.assign(result, {['key' + i]: i});    
    }    
    console.timeEnd('A');
}
testObject();//  A: 5.806884765625 ms