JS复制简单问题

一个对象 foo 有一个属性 baidu

var foo = {
    baidu:'woshibaidu'
    }

现在有一个对象 boo 引用了foo

    var boo = foo

所以此时,在boo里添加属性,或者修改属性,都会影响到foo,例如:此代码会在foo和boo里同时增加一个属性。

    boo.google = "imgoogle"

现在有问题来了。boo增加的google属性,会在foo出现,并且在boo修改时,foo内也会改变,如何做到boo引用foo内百度的值,但在foo内无法修改boo内google的值呢

阅读 2k
3 个回答

这样定义 boo 是不行的:

var boo = foo

这样定义 boo 才能达到你说的效果:

var boo = {
    get baidu () {
        return foo.baidu
    },
    set baidu (val) {
        foo.baidu = val
    },
    google: 'imgoogle'
}

你直接这样做的相当于是对一个对象的做浅拷贝。对于一个对象来说,你这样赋值是把boo指向了foo的堆里面(相可以想成:foo和boo指向同一个地址),所以你不论是改变foo还是boo都是改变的同一个东西。。。所以说如果你是只是要里面的值,你应该用深拷贝的方式:

`

var foo = {
    baidu:'woshibaidu'
}
var boo = JSON.parse(JSON.stringify(foo));
boo.baidu = "newBaidu"
boo.google = "imgoogle";

console.log(foo)    // {baidu: "woshibaidu"}
console.log(boo)    // {baidu: "newBaidu", google: "imgoogle"}

`

这样的方法便可以实现对象的深拷贝,但是有一个问题就是,如果你的对象里面有函数调用,就会跳过那个显示。所以如果有那种情况只能用递归来实现一个对象的深拷贝

如果你是想直接克隆一个对象,完全独立,如下:

function objClone(initalObj){
  var o = initalObj instanceof Array ? [] : {};
  for(var k in initalObj) {
    o[k] = (typeof(initalObj[k]) === 'object')&&(initalObj[k] != null) ? objClone(initalObj[k]) : initalObj[k];
  }
  return o;
}

var foo = {
  baidu:'woshibaidu'
};
var boo = objClone(foo);
boo.google = "imgoogle"; // foo.google为undefined
//foo与boo完全隔离,任何操作都不会有相互影响

如果你是想继承一个对象,然后再做修改,如下

function deepPrototypeClone(obj) {
  const ret = Object.create(obj);
  for (const [key, value] of Object.entries(obj)) {
    if (value && typeof value === 'object') {
      ret[key] = deepPrototypeClone(value);
    }
  }
  return ret;
}

var foo = {
  baidu:'woshibaidu'
};
var boo = deepPrototypeClone(foo);
boo.google = "imgoogle"; // foo.google为undefinded
//boo不会影响foo,但foo会影响boo(如果foo的某个属性没被boo重新赋值过)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题