14 JS中的引用與復(fù)制

作者:?緝熙Soyaine
簡(jiǎn)介:JavaScript30Wes Bos 推出的一個(gè) 30 天挑戰(zhàn)。項(xiàng)目免費(fèi)提供了 30 個(gè)視頻教程、30 個(gè)挑戰(zhàn)的起始文檔和 30 個(gè)挑戰(zhàn)解決方案源代碼。目的是幫助人們用純 JavaScript 來(lái)寫東西,不借助框架和庫(kù),也不使用編譯器和引用?,F(xiàn)在你看到的是這系列指南的第 14 篇。完整指南在 GitHub,喜歡請(qǐng) Star 哦?(?*)

創(chuàng)建時(shí)間:2017-07-19
最后更新:2017-07-21

實(shí)現(xiàn)效果

這個(gè)部分主要是幫助你通過(guò)不同的語(yǔ)句來(lái)感受在 JavaScript 中對(duì)不同類型數(shù)據(jù)的引用(Reference)和復(fù)制(Copy)的區(qū)別。由于操作在 Console 中進(jìn)行,所以請(qǐng)直接運(yùn)行頁(yè)面后打開(kāi) Console,邊編輯代碼,邊查看結(jié)果。

過(guò)程指南

  1. 首先從 String、Number、Boolean 類型的值開(kāi)始。

    let age = 100;
    let age2 = age;
    console.log(age, age2); // 100 100
    age = 200;
    console.log(age, age2); // 200 100
    

    先聲明了一個(gè) Number 型的變量 age,并將此變量賦值給另一個(gè)變量 age2,這時(shí)兩個(gè)變量的值都是 100。
    然后賦給 age 新的值,可見(jiàn)對(duì) age 的修改并不會(huì)對(duì) age2 造成影響。

  2. 那對(duì)于數(shù)組來(lái)說(shuō),情況是否一樣呢?下面我們來(lái)看看數(shù)組。

    const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];
    const team = players;
    console.log(players, team);
    

    延續(xù)上面的思路,先聲明一個(gè)數(shù)組 players,并將其賦值給 team。試想一下,如果需要修改 team 中的值,我們可以如何操作?或許可以這樣?

    team[3] = 'Lux';
    

    來(lái)看看發(fā)生了什么。

    console.log(players, team); 
    // ["Wes", "Sarah", "Ryan", "Lux"] ["Wes", "Sarah", "Ryan", "Lux"]
    

    WOW 原數(shù)組 plaryers 也被修改了。為什么會(huì)這樣?因?yàn)?team 只是這個(gè)數(shù)組的引用,并不是它的復(fù)制。teamplayers 這兩個(gè)變量指向的是同一個(gè)數(shù)組。
    所以如何解決這個(gè)問(wèn)題?接下來(lái)我們開(kāi)始真正的復(fù)制吧!

    • 方法一 Array.prototype.slice()

      由于運(yùn)行 slice 得到的結(jié)果是一個(gè)對(duì)原數(shù)組的淺拷貝,原數(shù)組不會(huì)被修改。所以如果修改這兩個(gè)數(shù)組中任意 一個(gè),另一個(gè)都不會(huì)受到影響。

      const team2 = players.slice();
      team2[3] = 'Lux2';
      console.log(players, team2); 
      
    • 方法二 Array.prototype.concat()

      concat() 方法是用來(lái)合并數(shù)組的,它也不會(huì)更改原有的數(shù)組,而是返回一個(gè)新數(shù)組,所以可以將 players 數(shù)組與一個(gè)空數(shù)組合并,得到的結(jié)果就符合預(yù)期了。

      const team3 = [].concat(players);
      team3[3] = 'Lux3';
      console.log(players, team3); 
      
    • 方法三 ES6 擴(kuò)展語(yǔ)法

      擴(kuò)展語(yǔ)法可以像擴(kuò)展參數(shù)列表一樣來(lái)擴(kuò)展數(shù)組,效果與上述方法類似,但比較簡(jiǎn)潔。

      const team4 = [...players];
      team4[3] = 'Lux4';
      console.log(players, team4);
      
    • 方法四 Array.from()

      此外使用 Array 創(chuàng)建新的數(shù)組實(shí)例的方法也是可行的。

      const team5 = Array.from(players);
      team5[3] = 'Lux5';
      console.log(players, team5);
      

    除此之外,還可以用 push 這樣的方法。數(shù)組部分已經(jīng)介紹完畢,下面我們進(jìn)入 Object 類型數(shù)據(jù)的試驗(yàn)吧~

  3. 對(duì)于 Object 數(shù)據(jù),我們用一個(gè) person 對(duì)象來(lái)試試。

    先聲明對(duì)象:

    const person = {
       name: 'Wes Bos',
       age: 80
     };
    

    然后思考一下如何可以取得它的復(fù)制,試試想當(dāng)然的做法:

    const captain = person;
    captain.number = 99;
    console.log(person, captain);
    // Object {name: "Wes Bos", age: 80, number: 99} 
    // Object {name: "Wes Bos", age: 80, number: 99}
    

    這樣好像行不通,person 的值也被更改了,那該如何才能真正復(fù)制呢?

    • 方法一 Object.assign()

      使用 Object.assign(target, ...sources) 時(shí),后來(lái)的源對(duì)象的屬性值,將會(huì)覆蓋它之前的對(duì)象的屬性。所以可以先復(fù)制 person 之后,再賦給屬性新的值。

      const cap2 = Object.assign({}, person, { number: 99, age: 12 });
      console.log(cap2); // Object {name: "Wes Bos", age: 12, number: 99}
      
    • 方法二 JSON 轉(zhuǎn)換

      利用 JSON 可以先將對(duì)象轉(zhuǎn)成字符串的格式,然后再把它轉(zhuǎn)成 JSON,從而實(shí)現(xiàn)復(fù)制。

      const wes = {
        name: 'Wes',
        age: 100,
        social: {
          twitter: '@wesbos',
          facebook: 'wesbos.developer'
        }
      };
      
      const dev = Object.assign({}, wes);
      const dev2 = JSON.parse(JSON.stringify(wes));
      console.log(wes);
      console.log(dev);
      console.log(dev2);
      

最后需要注意的是:在前面的例子里面,我們用的數(shù)組和對(duì)象都只是一層嵌套,Lodash 有一個(gè)深度復(fù)制的方法,但你使用之前需要多考慮一下。

OVER(^o^)/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式。簡(jiǎn)單...
    舟漁行舟閱讀 8,115評(píng)論 2 17
  • JavaScript之父:Brendan Eich 。 -基本語(yǔ)法:借鑒了C語(yǔ)言和Java語(yǔ)言。-數(shù)據(jù)結(jié)構(gòu):借鑒了...
    饑人谷_kule閱讀 665評(píng)論 0 0
  • var a = 1; console.log(typeof a);// 'number' var b = '1';...
    zdnexus閱讀 401評(píng)論 0 0
  • toStirng()與Object.prototype.toString.call()方法淺談 一、toStrin...
    Michael_林閱讀 1,120評(píng)論 1 4
  • 日子變得越來(lái)越忙碌 心境卻越來(lái)越淡薄 最大的進(jìn)步在于認(rèn)清自己的不足 努力去revised 從前的被塞滿的日子 精修...
    水筆仔o12530閱讀 177評(píng)論 0 0

友情鏈接更多精彩內(nèi)容