Object.assign()方法用于从一个或多个源对象(sources)中拷贝所有可枚举的自有属性到目标对象(target),并返回目标对象。拷贝过程中将调用源对象的getter方法,并在target对象上使用setter方法实现目标对象的拷贝。
1
| Object.assign(target, ...sources)
|
不过,采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码。
原文:Both String and Symbol properties are copied.
String和Symbol类型都可被直接分配。
1 2 3 4
| function clone(origin) { let originProto = Object.getPrototypeOf(origin); return Object.assign(Object.create(originProto), origin); }
|
注意:如果属性是只读的,那将会抛出异常,目标对象将会停止改变(而之前的改变会保留)。但是对于null或者undefind会直接忽略。
简单克隆对象
1 2 3 4
| var obj = ; var copy = Object.assign(, obj); console.log(copy);
|
合并对象
1 2 3 4 5 6
| var a = {x: 1}; var b = {y: 2}; var c = {x: 4, z: 3}; var obj = Object.assign(a, b, c); console.log(obj);
|
拷贝Symbol属性
1 2 3 4 5
| var a = {x: 1}; var b = {[Symbol('y')]: 2}; var obj = Object.assign(a, b); console.log(obj);
|
继承的属性和不可枚举的属性不会被拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var obj = Object.create({foo: 1}, { a: { value: 2 }, b: { value: 3, enumerable: true } } ); var copy = Object.assign({}, obj); console.log(copy);
|
字符串会被转成object
1 2 3 4 5 6 7 8 9 10 11 12 13
| var str = 'hejx'; var obj = Object.assign({}, str); console.log(obj); var a = "123"; var b = false; var c = 123; var d = Symbol('sy'); var e = Object.assign({}, a, b, c, d, null, undefined); console.log(e);
|
只读属性不能被拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13
| var target = Object.defineProperty({}, 'foo', { value: 1, writable: false }); Object.assign(target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 }); console.log(target.bar); console.log(target.foo2); console.log(target.foo); console.log(target.foo3); console.log(target.baz);
|
拷贝属性的赋值器(setter)和取值器(getter)
1 2 3 4 5 6 7 8 9 10 11 12
| var obj = { a: 1, get b(){ return 2; }, someMethod(){ } }; var copy = Object.assign({}, obj); console.log(copy);
|
es5版本的Object.assign
不支持Symbol属性,因为es5压根没有Symbol
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| if (typeof Object.assign != 'function') { (function () { Object.assign = function (target) { 'use strict'; if (target === undefined || target === null) { throw new TypeError('Cannot convert undefined or null to object'); } var output = Object(target); for (var index = 1; index < arguments.length; index++) { var source = arguments[index]; if (source !== undefined && source !== null) { for (var nextKey in source) { if (source.hasOwnProperty(nextKey)) { output[nextKey] = source[nextKey]; } } } } return output; }; })(); }
|
不支持深度拷贝
1 2 3 4
| var target = { a: { b: 'c', d: 'e' } } var source = { a: { b: 'hello' } } Object.assign(target, source)
|
深度拷贝
拷贝数组
1 2 3 4
| var arr = [1, 2, 3]; //会被当成对象 var str = "4567"; var copy = Object.assign({}, arr, str); console.log(copy); // Object {0: "4", 1: "5", 2: "6", 3: "7"}
|
兼容性
属于es6规范,然而兼容性并不好,pc端除了ie,其他都支持。移动端目前就Firefox Mobile 支持。
文献
摘自developer.mozilla.org
es6.ruanyifeng.com
ES2015系列(二) 理解Object.assign