JS:.push()方法意外继承

时间:2019-03-26 19:31:31

标签: javascript object inheritance

我现在正在开发一些在画布上运行的游戏引擎。我有一些基本知识,但现在我想添加父母和孩子...一切运行正常,直到我尝试将对子对象的引用添加到父对象。我的问题很短:

// Object that will be parent of obj1
var obj0 = {
  childs: [],
  someValue: 10,
  parent: null
}

// obj1 is defined from obj0 throught Object.assign(), so any change in
// obj1 will NOT reflect to obj0 (I added console.log() to show it)
var obj1 = Object.assign({}, obj0);
console.log("Expected result: false; Result: " + (obj0 == obj1));
obj1.someValue = 5;
console.log("Expected result: false; Result: " + (obj0.someValue == obj1.someValue));

// Now add obj0 as parent to obj1...
obj1.parent = obj0;

// ... and add obj1 as child to obj0 - I need to do this throught .parent
// (I can't directly do some change in obj1)
obj1.parent.childs.push(obj1);

// Everything seems be alright, but... If I look into obj1.childs...
console.log(obj1.childs)
// I see, that .push applied to all objects that are...

如何看到,.push()方法应用于所有对象(在这种情况下,两个对象都适用)。

所以我的问题:
1.为什么?
2.如何避免?

提前谢谢...

2 个答案:

答案 0 :(得分:2)

// Observable for data const data$ = fetchData('https://jsonplaceholder.typicode.com/posts'); // Observable for user leave const userLeave$ = trackUserPresence(); data$ .takeUntil(userLeave$) .subscribe(data => console.log(data)) 之后,obj1 = Object.assign({}, obj0)obj0都引用相同的obj1数组。因此,无论您带入该数组的任何突变(例如,childs),都可以通过两个对象看到。

摆脱这种不良影响的一种方法是创建一个构造函数(JavaScript的特殊功能),甚至可能使用push表示法:

class

答案 1 :(得分:1)

根据评论,问题在于Object.assign是一个浅表副本,并且最终两个对象的childs属性是同一数组,因此当您push一个childs数组,另一个数组也被更新(两个childs数组都是相同的)。

也许您想使用一个类来定义对象:

// Object that will be parent of obj1
class MyObj {
  constructor() {
    this.childs = [];
    this.someValue = 10;
    this.parent = null;
  }
}

var obj0 = new MyObj();
var obj1 = new MyObj();
console.log("Expected result: false; Result: " + (obj0 == obj1));
obj1.someValue = 5;
console.log("Expected result: false; Result: " + (obj0.someValue == obj1.someValue));

// Now add obj0 as parent to obj1...
obj1.parent = obj0;

// ... and add obj1 as child to obj0 - I need to do this throught .parent
// (I can't directly do some change in obj1)
obj1.parent.childs.push(obj1);

console.log("obj0's children:")
console.log(obj0.childs)
console.log("obj1's children:")
console.log(obj1.childs)