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 (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,
});
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) {
;
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