美文网首页
Node.js Object.assign的一个小问题

Node.js Object.assign的一个小问题

作者: Nardy | 来源:发表于2018-07-12 11:13 被阅读250次

    前不久,在开发【快捎】项目时,发现了一个Object.assign问题:
    先上代码:

    var config = {
      token: "abcdefghijklmn",
      db: 0,
      retriesStrategy: {
        timeout: 2500,
        retries: 10,
        autoload: true
      }
    };
    //对象复制
    var cfg1 = Object.assign({}, config);
    var cfg2 = Object.assign({}, config);
    //...
    function cnt1(cfg) {
      cfg.retriesStrategy.autoload = false;
      //@TODO Connection to ssdb1
    }
    function cnt2(cfg) {
      //@TODO Connection to ssdb2
    }
    
    cnt1(cfg1)
    cnt2(cfg2)
    

    上面代码中,本来定义是ssdb1是不需要主动载入的,而ssdb2则需要主动载入。按照之前的理解,使用Object.assign(obj1, obj2)的用法,应该是把obj2的成员复制到obj1中,,然后返回obj1。但答案却不是这样子,就上面的代码,造成了两个数据库都不会主动载入了。

    经过一翻折腾,牺牲了本王5分钟的睡眠时间,终于把问题定位在Object.assign函数这里,以下是我的理解, 先上分析图:


    9c16fdfaaf51f3de4ec91fb390eef01f3b2979ea.jpg

    啊不,发错了!!嘻嘻嘻~~~


    image.png

    从上图结合js的对象引用特性可以看出,Object.assign只是一个浅拷贝函数,当前使用上面Object.assign({}, config)时,仅仅是把config中第一层的对象属性copy了一份到一个空对象中,然而在原来的config对象中,有一个子对象retriesStrategy, 一直引用着自己的一块对象内存, 所以,在函数cnt1中修复了retriesStrategy下的autoreload属性时, 也直接修改了其引用的堆内存。当cnt2函数中使用cfg1时,实际上是使用被修改过的retriesStrategy。

    引申一下,在node.js中,数组(Array)和对象(Object)都是引用类型,以上出现的问题,在数组中同样也会出现。大家在使用时,要多多注意!!

    相关文章

      网友评论

          本文标题:Node.js Object.assign的一个小问题

          本文链接:https://www.haomeiwen.com/subject/tgylpftx.html