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

Gau*_*tri 3 javascript ecmascript-6

我正在尝试理解我在ES6课程中观察到的这种行为.请考虑以下代码.这很简单:我有一个父类(Parent)和一个Child继承自它的子类().Parentclass有一个方法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".
Run Code Online (Sandbox Code Playgroud)

我不确定为什么会这样!

我所做的是改变了我getLabelParent课堂上定义方法的方式:

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.
Run Code Online (Sandbox Code Playgroud)

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

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

Ori*_*iol 7

那是因为getLabel在每个实例中都定义了它,它不会在原型中共享.并且由于您使用箭头函数定义它,它没有定义本地绑定this,因此该this值将是其中之一constructor.

然后,当你使用Object.assign,c1接收的方法c,和this值将是c,即使你调用它c1.所以你得到了c.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"
Run Code Online (Sandbox Code Playgroud)

(注意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"
Run Code Online (Sandbox Code Playgroud)

  • 这是我今天看到的第二个问题,问题是由于使用了箭头功能.我猜人们会爱上它更简单的语法,并没有意识到它在行为上有这种显着的差异. (3认同)