语法
1
| Object.assign(target, ...sources);
|
该方法用于将一个或多个源对象的 所有可枚举属性值 复制到目标对象。
返回值就是 target 对象。
内部实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| if (!Object.assign) { // 定义assign方法 Object.defineProperty(Object, 'assign', { enumerable: false, configurable: true, writable: true, value: function(target) { // assign方法的第一个参数 'use strict'; // 第一个参数为空,则抛错 if (target === undefined || target === null) { throw new TypeError('Cannot convert first argument to object'); } var to = Object(target); // 遍历剩余所有参数 for (var i = 1; i < arguments.length; i++) { var nextSource = arguments[i]; // 参数为空,则跳过,继续下一个 if (nextSource === undefined || nextSource === null) { continue; } nextSource = Object(nextSource); // 获取改参数的所有key值,并遍历 var keysArray = Object.keys(nextSource); for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) { var nextKey = keysArray[nextIndex]; var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); // 如果不为空且可枚举,则直接浅拷贝赋值 if (desc !== undefined && desc.enumerable) { to[nextKey] = nextSource[nextKey]; } } } return to; } }); }
|
示例
1 2 3 4 5 6 7
| // Merging objects var o1 = { a: 1 }; var o2 = { b: 2 }; var o3 = { c: 3 }; var obj = Object.assign({}, o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 }
|
- 目标对象的属性值会被源对象同名属性值覆盖,哪怕二者类型不同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var sourceObj = { name:"sourceObj", time : { year:"2019", month:"1" } }
var targetObj = { name:"targetObj", time : "2020.1" };
Object.assign(targetObj, sourceObj) console.log(targetObj)
|
输出为:
1 2 3 4 5 6 7
| { name:"sourceObj", time : { year:"2019", month:"1" } }
|
如果对象的属性值为简单类型(string, number),通过 Object.assign({},srcObj); 得到的新对象为‘深拷贝’;
如果属性值为对象或其它引用类型,那对于这个对象而言其实是浅拷贝的。这是Object.assign()特别值得注意的地方。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| var sourceObj = { name:"sourceObj", time : { year:"2019", month:"1" } }
var targetObj = { name:"targetObj", time : { year:"2020", month:"1" } };
Object.assign(targetObj, sourceObj)
sourceObj.name = "newSourceObj" sourceObj.time.year = "new2019"
console.log(targetObj)
|
输出为:
1 2 3 4 5 6 7
| { name:"sourceObj", time : { year:"new2019", month:"1" } }
|
完全深拷贝
一个可以简单实现深拷贝的方法,当然,有一定限制,如下:
1
| const obj1 = JSON.parse(JSON.stringify(obj));
|
思路就是将一个对象转成 json 字符串,然后又将字符串转回对象。