JS30 Day 14 - JavaScript References VS Copying学习笔记

这个章节比较偏观念,如浅複製及深複製的一些概念,我觉得是非常重要的重点。

start with strings, numbers and booleans

首先是字串、数值、布林值的赋值

    let a = "A";    let b = a;    a = "B";    console.log(a, b); //  B,A    let c = 0;    let d = c;    c++;    console.log(c, d); //  1,0    let e = true;    let f = e;    e = !f;    console.log(e, f); // false,true

发现记忆体没有A就创建一个A值并赋予记忆体位置,再将g,h,i指向,A的记忆体位置,再来找B,C都没有,就创建B,C并赋予记忆体位置,再来h指向B记忆体位置,i指向C记忆体位置,最后将g+h=AB并赋予记忆体位置,g指向AB记忆体位置,接着g+i=ABC并赋予记忆体位置,g指向AB记忆体位置。

    let g = "A";    let h = "A";    let i = "A";    h = "B", i = "C", g += h, g += i;    console.log(g, h, i); //ABC , B ,C

http://img2.58codes.com/2024/20126182AD6m6hVrCU.png

Let's say we have an array

接着是做关于阵列的複製。

    const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];    let player2 = players;    player2[0] = "jojo";    console.log(players, player2);    [0: "jojo",1: "Sarah",2: "Ryan",3: "Poppy"] [0: "jojo",1: "Sarah",2: "Ryan",3: "Poppy"]

发现这并不是我们所要得複製,他们都对应到同一个阵列,所以利用以下几种方法,可达到互不影响的複製。

法1:slice()方法,利用slice可达到複製,因为slice会额外再产生一个新的阵列。

    let player2 = players.slice();    player2[0] = "jojo";    console.log(players, player2);    (4) ["Wes", "Sarah", "Ryan", "Poppy"] (4) ["jojo", "Sarah", "Ryan", "Poppy"]

法2:concat()方法,被用来合併两个或多个阵列。此方法不会改变现有的阵列,会回传呼叫者阵列本身,也就是与players的值合併后的空阵列。

    let player2 = [].concat(players);    player2[0] = "jojo";    console.log(players, player2);

法3:解构赋值,将players中的值拆分出来,在合併至player2,回传一个新的阵列。

    let player2 = [...players];    player2[0] = "jojo";    console.log(players, player2);

再来是配合呼叫函数所产生的阵列複製。

    function createObj(name) {      return {        //name:name         name      };    }    let pr1 = createObj("johnny");    let pr2 = createObj("lisa");    let pr3 = createObj("iggy");    let gr1 = [pr1, pr2, pr3];    let gr2 = gr1.slice();    // 由于gr2[0]值为pr1,所以他会去改变gr2[0].name,也就是pr1的值,那我再次获取gr1,它里面的pr1也会是改变后的值。    gr2[0].name = "momo";    console.log(gr1, gr2); // (3) ["momo", "lisa", "iggy"]     // 但如果改为这样,可发现两者已互不影响,因为记忆体发现我们的记忆体中并无momo这个值,所以他会创建一个momo的值,并给予他一个记忆体空间,而后我们gr2[0](也就是gr2的pr1)就会指向他,并不影响。    gr2[0] = "momo";    console.log(gr1, gr2); // (3) ["johnny", "lisa", "iggy"]  (3) ["momo", "lisa", "iggy"] 

http://img2.58codes.com/2024/201261823sTZgeJG1D.png

with Objects

接下来是物件之间的複製与赋值。

    let person = {      name: 'Wes Bos',      age: 80    };    let p1 = person;    // 查看记忆体无XXX后,创建一个XXX的值并赋予记忆体空间,接着person在指向他,而与p1互不影响。    person = "XXX";    console.log(person, p1); // XXX,{...}    // 前面步骤与上面一样,不同的是会改变person.name的值也就是0x1的name,因此p1也会受影响,因为p1指向的也是person所指向的0x1。        person.name = "XXX";    console.log(person, p1); // {XXX...},{XXX...}

http://img2.58codes.com/2024/20126182dpX6oQO9e8.png

将物件x,y合併后,赋予z,会发现后者的重複的name可以覆盖前者的。

    let x = {      name: "bogi",      age: 87    };    let y = {      name: "dandy"    };    let z = Object.assign(x, y);    console.log(z); // {name: "dandy", age: 87}

如果我们今天在物件新增一个函数,然后以kk複製他并一样先字串化,然后再转回obj化,会发现再以kk呼叫就会报错,因为经stringify,function会被lose掉

    let k = {      name: "eva",      age: 22,      eat: function () {        console.log("amazing");      }    };    let kk = JSON.parse(JSON.stringify(k));    // k.eat()  // amazing    // kk.eat() // Uncaught TypeError: kk.eat is not a function at <anonymous>:1:4

如果今天我们的物件不含函数,那么利用JSON.parse(JSON.stringify(wes)),就可以达到deep copy,但如果有就无法。

    const wes = {      name: 'Wes',      age: 100,      social: {        twitter: '@wesbos',        facebook: 'wesbos.developer'      }    };    const dev = Object.assign({}, wes);    // 第一题    // 互不影响    dev.social = null;    console.log(wes); // 不变 {twitter...};     // 第二题    dev.social.facebook = null;    console.log(wes.social); // {twitter:..., facebook:null}    const dev3 = JSON.parse(JSON.stringify(wes));    

第一题

http://img2.58codes.com/2024/20126182YLg1nLeNlC.png

第二题

http://img2.58codes.com/2024/20126182BJKWlWFn89.png

第三题:
首先将wes(0x6)的资料,经由stringify将0x6拿出来,并赋予一个新的记忆体空间0x8,再来经过parse,将0x5的资料拿出来(因为0x5为物件(或阵列或函数)资料就会重新赋予记忆体空间)0x9,而后重新创建一个记忆体空间0x10让wes3指向他。

http://img2.58codes.com/2024/201261821aoF8MI3eI.png


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章