亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

ES6+ Object.assign()

1. 前言

Object 對象的更新 把一個對象復制到另一個對象,在 ES5 中需要循環對象進行拷貝

2. 方法詳情

2.1 基本語法

語法使用:

Object.assign(target, ...sources)

參數解釋:

參數 描述
target 需要拷貝到的目標對象
sources 源對象

2.2 拷貝對象

let target = {};
let source = {a: 1, b: 2, c: 3};
Object.assign(target, source);
target.d = 4;
console.log(target)   // {a: 1, b: 2, c: 3, d: 4}
console.log(source)   // {a: 1, b: 2, c: 3}

上面的代碼可以看出,Object.assign () 的主要用法就是把源對象拷貝到指定的對象上去,目標對象的更改不會影響源對象。

2.3 合并對象

let target = {a: 1};
let source1 = {b: 2};
let source2 = {c: 3};
Object.assign(target, source1, source2);
console.log(target);  // {a: 1, b: 2, c: 3}

上面的代碼可以看出,Object.assign () 不會把目標對象清空,會合并后面所有的對象上的值。

2.4 覆蓋前面的值

let target = {a: 1, b: 1};
let source1 = {b: 2, c: 2};
let source2 = {c: 3};
Object.assign(target, source1, source2);
console.log(target);  // {a: 1, b: 2, c: 3}

如果后面的源對象上有相同的值,后面的源對象會覆蓋前面對象上的值,這一點需要注意。

3. 淺拷貝

Object.assign() 的拷貝屬于淺拷貝,也就是說它只拷貝對下的第一層的屬性值。如果這個值是一個對象類型,那么 Object.assign() 不會對該對象進行深拷貝,也就是說,拷貝后的對象下的這個對象類型是源對象和拷貝后的對象共有的,無論誰(源對象或拷貝后對象)對這個對象下的值進行修改,另一個對象(源對象或拷貝后對象)也會共享這個改變??聪旅娴睦痈逦谋磉_:

var target = {};
var source = {a: 1, b: {c: 2, d: 3}};
Object.assign(target, source);
target.a = 5;
target.b.c = 9;
console.log(target)   // {a: 5, b: {c: 9, d: 3}}
console.log(source)   // {a: 1, b: {c: 9, d: 3}}

上面的代碼中,源對象 source 是個兩層的字面量對象,b 也是一個對象。使用 Object.assign() 拷貝給目標對象 target,拷貝后對 target 對象下的值進行修改,然后打印目標對象和源對象。從打印的結果可以看出,對 target 第一層的 a 進行修改時,源對象是不會改變。但是對 target 下的 b 對象下的值進行修改時,因為 b 也是一個對象,所以源對象中的值也被修改了。到這里可以看出,Object.assign() 沒有對 b 進行拷貝。

如果需要深拷貝則需要,需要遞歸地使用去 Object.assign() 來拷貝對象。

4. 基本類型的合并

當合并的源對象是基本類型時,這些基本類型會作為最后對象上的值,而鍵則以數字遞增,其中如果值是 null 和 undefined 時會被忽略??慈缦聦嵗?/p>

var s1 = "abc";
var s2 = true;
var s3 = 10;
var s4 = Symbol("foo")
var obj = Object.assign({}, s1, null, s2, undefined, s3, s4);
console.log(obj); // { "0": "a", "1": "b", "2": "c" }

5. 拷貝異常時會被打斷

在拷貝時如果發生異常,則拷貝會被終止,并報錯,前面已經被拷貝的不會被影響可以繼續使用,但后面沒有被拷貝的則不能被使用。

var target = Object.defineProperty({}, "a", {
  value: 1,
  writable: false
});
Object.assign(target, {b: 2}, {a: 3}, {c: 4});
// Uncaught TypeError: Cannot assign to read only property 'a' of object '
console.log(target.b);  // 2
console.log(target.c);  // undefined

上面的代碼中,定義了目標對象 target 上的屬性 a 是只讀的,也就是不能不被修改,在合并代碼時,源對象上有 a,則報了 a 是對象上的只讀屬性不能被 assign 操作。從后面的打印結果可以看出,b 已經被拷貝到目標對象上了可以正常使用,但由于拷貝中發生異常,最后一個對象沒有被拷貝,所以 c 的值是 undefined。

6. 小結

本章講解了用于合并對象的方法 Object.assign() 主要有以下幾點需要注意的。

  • Object.assign () 屬于淺拷貝;
  • 合并對象時后面的對象會覆蓋前面的對象;
  • 拷貝時發生異常,前面已拷貝的不會受到影響,異常后面的對象則不會被拷貝。