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

前不久,在开发【快捎】项目时,发现了一个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函数这里,以下是我的理解, 先上分析图:


Node.js Object.assign的一个小问题_第1张图片
9c16fdfaaf51f3de4ec91fb390eef01f3b2979ea.jpg

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


Node.js Object.assign的一个小问题_第2张图片
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的一个小问题)