prefer-object-spread

eslint報錯:數組

  Use an object spread instead of `Object.assign` eg: `{ ...foo }`.(prefer-object-spreadspa

即:eslint

  禁止使用以對象字面量做爲第一個參數的 Object.assign,優先使用對象擴展。
code

 

 

示例:(注意:對象字面量)對象

Object.assign({}, foo)

改成:

{ ...foo }



思考一下:
Object.assign經常使用來淺拷貝,那擴展符賦值的對象是從新開闢的堆內存仍是指向的擴展對象的堆內存?

    const a = { a: 'a' };
    const b = { ...a };
    console.log('b=', b);  // b= {a: "a"}
    a.a = 'c';
    console.log('b變了嗎', b); // b變了嗎 {a: "a"}   

  

  答案很明顯,我想淺拷貝一個a, 擴展運算符和Object.assign都能淺拷貝對象blog

 

  那數組會怎樣?內存

  

    const a = ['a', 'b'];
    const b = [...a];
    console.log('b=', b);  // b= ["a", "b"]
    a[1] = 'c';
    console.log('b變了嗎', b); // b變了嗎 ["a", "b"]

 

  很好,數組也能放心的淺拷貝;string

  

  等等。。。console

  

  若是是數組對象呢?class

 

    const a = [{ a: 'a' }];
    const b = [...a];
    console.log('b=', JSON.stringify(b));  // b= [{"a":"a"}]
    a[0].a = 'c';
    console.log('b變了嗎', JSON.stringify(b)); // b變了嗎 [{"a":"c"}]

 

  變了,結果說明展開符只對數組裏面的對象進行了展開,對象裏面的屬性仍是指向的原來的內存地址,因此深拷貝行不通,目前來看和Object.assign的淺拷貝做用同樣。

 

那...等等,

  

  Object.assign還有合併的做用,再來試試擴展符合並。

  

  

    const a = { a1: 'a1', a2: 'a2' };
    const b = { b1: 'b1', a2: 'b2' };
    const c = Object.assign({}, a, b);
    const d = { ...a, ...b };
    const e = { ...b, ...a };
    console.log('c', c);  // c {a1: "a1", a2: "b2", b1: "b1"}
    console.log('d', d);  // d {a1: "a1", a2: "b2", b1: "b1"}
    console.log('e', e);  // e {b1: "b1", a2: "a2", a1: "a1"}

 

   結果同樣,Object.assign將b和a的屬性合併到空對象裏,相同屬性會覆蓋合併取後面的值,擴展符直接合並兩個對象的屬性,合併關係都是後面的覆蓋前面的值

 

   那麼,合併數組呢?

 

    const a = ['a', 'b'];
    const b = ['a', 'c'];
    const c = Object.assign([], a, b);
    const d = [...a, ...b];
    console.log('c', c);  // c ["a", "c"]
    console.log('d', d);  // d ["a", "b", "a", "c"]

 

   發生了什麼?

   Object.assign處理數組時,會把數組視爲對象,而後按順序覆蓋前面的值,因此b中的'a'覆蓋了a中的'a', b中的'c'覆蓋了a中的'b',而擴展符和concat方法同樣合併數組

 

   合併數組時,Object.assign和擴展符做用不同了。

   

   那麼,複雜數組呢?

    const a = [{ x: 'x', y: 'y' }];
    const b = [{ z: 'z', y: 'm' }];
    const c = Object.assign([], a, b);
    const d = [...a, ...b];
    console.log('c', JSON.stringify(c)); // c [{"z":"z","y":"m"}]
    console.log('d', JSON.stringify(d)); // d [{"x":"x","y":"y"},{"z":"z","y":"m"}]
    b[0].z = 'n';
    console.log('c', JSON.stringify(c)); // c [{"z":"n","y":"m"}]
    console.log('d', JSON.stringify(d)); // d [{"x":"x","y":"y"},{"z":"n","y":"m"}]

  

  Object.assign毫無懸念的後面的覆蓋前面了(將數組看作對象時,屬性就是下標),引用類型指向的仍是原來的內存地址

  

 

最後:

  

  雖說Object.assign和...擴展符不少時候能混用,但對數組進行操做的時候必定要當心二者的區別,否則合併覆蓋變成合並拼接,因此請牢記使用以對象字面量做爲第一個參數的 Object.assign,優先使用對象擴展

本站公眾號
   歡迎關注本站公眾號,獲取更多信息