试图理解ES6中的Object.assign行为

时间:2016-08-22 19:06:01

标签: javascript ecmascript-6

我正在尝试理解我在ES6课程中观察到的这种行为。请考虑以下代码。这很简单:我有一个父类(Parent)和一个继承自它的子类(Child)。 Parent类有一个名为getLabel的方法,它只返回该类的label属性。

当我创建子类的实例时,设置其标签并尝试打印它一切正常。

但是,当我在第一个实例上使用Object.assign创建另一个子类实例时,即使我明确地更改它,新实例也会保留第一个实例的标签值。

class Parent {
  constructor(label) {
    this.getLabel = () => {
      return this.label;
    };
    this.label = label;
  }
}

class Child extends Parent {
  constructor(label) {
    super(label);
    this.label = label;
  }
}

const c = new Child('Child');
console.log('c getLabel() = ' + c.getLabel());//Prints "Child"
const c1 = Object.assign(new Child('C1'), c);
c1.label = 'Child Modified';
console.log('c1 getLabel() = ' + c1.getLabel());//Prints "Child" again instead of "Child Modified".

我不确定为什么会发生这种情况!

我所做的改变了我在getLabel类中定义Parent方法的方式:

class Parent2 {
  constructor(label) {
    this.label = label;
  }

  getLabel() {
    return this.label;
  }
}

class Child2 extends Parent2 {
  constructor(label) {
    super(label);
    this.label = label;
  }
}

const c2 = new Child2('Child 2');
console.log('c2 getLabel() = ' + c2.getLabel());//Prints "Child 2" as expected.
const c3 = Object.assign(new Child2('C3'), c2);
c3.label = 'Child 2 Modified';
console.log('c3 getLabel() = ' + c3.getLabel());//Prints "Child 2 Modified" as expected.

如果有人能解释这两种不同的行为,我将不胜感激。

以上代码的ES6小提琴:http://www.es6fiddle.net/is6ex359/

1 个答案:

答案 0 :(得分:7)

因为getLabel是在每个实例中定义的,所以它不会在原型中共享。由于您使用箭头函数定义它,因此它不会为this定义本地绑定,this值将是constructor之一。

然后,当您使用Object.assign时,c1会收到c的方法,this值将为c,即使您将其称为c1c.label。所以你得到'Child',仍然是class Parent { constructor(label) { this.label = label; } getLabel() { return this.label; } } class Child extends Parent { constructor(label) { super(label); this.label = label; } } const c = new Child('Child'); console.log('c getLabel() = ' + c.getLabel()); // "Child" const c1 = Object.assign(new Child('C1'), c); c1.label = 'Child Modified'; console.log('c1 getLabel() = ' + c1.getLabel()); // "Child Modified"

所以你应该避免箭头功能。我建议在原型中定义方法:



Object.assign




(注意getLabel未分配c1.getLabel ==== c.getLabel,因为它已继承,但class Parent { constructor(label) { this.getLabel = function() { return this.label; }; this.label = label; } } class Child extends Parent { constructor(label) { super(label); this.label = label; } } const c = new Child('Child'); console.log('c getLabel() = ' + c.getLabel()); // "Child" const c1 = Object.assign(new Child('C1'), c); c1.label = 'Child Modified'; console.log('c1 getLabel() = ' + c1.getLabel()); // "Child Modified"无论如何)

或者在构造函数中,但使用函数表达式:



{{#get "posts" filter="tags:xyz"}}
  {{#foreach posts}}
    yeah posts
  {{/foreach}}
{{else}}
  no posts found
{{/get}}