Javascript 试图理解ES6中的Object.assign行为
我试图理解我在ES6课程中观察到的这种行为。考虑下面的代码。它非常简单:我有一个父类(Javascript 试图理解ES6中的Object.assign行为,javascript,ecmascript-6,Javascript,Ecmascript 6,我试图理解我在ES6课程中观察到的这种行为。考虑下面的代码。它非常简单:我有一个父类(parent)和一个子类(child)继承自它Parent类有一个名为getLabel的方法,该方法只返回该类的label属性 当我创建一个子类的实例时,设置它的标签并尝试打印它,这一切都很好 但是,当我在第一个实例上使用Object.assign创建子类的另一个实例时,新实例保留第一个实例的标签值,即使我正在显式更改它 class Parent { constructor(label) { thi
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".
我不知道为什么会这样
然后我所做的改变了我在Parent
类中定义getLabel
方法的方式:
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对上述代码的处理:。这是因为
getLabel
在每个实例中都有定义,但在原型中没有共享。由于您使用箭头函数定义它,因此它没有为this
定义本地绑定,this
值将是构造函数的值之一
然后,当您使用Object.assign
时,c1
接收c
的方法,该值将是c
,即使您在c1
上调用它也是如此。所以你得到了c.label
,它仍然是的“孩子”
所以你应该避免使用箭头函数。我建议在原型中定义方法:
类父类{
建造师(标签){
this.label=标签;
}
getLabel(){
返回此.label;
}
}
类子级扩展父级{
建造师(标签){
超级(标签);
this.label=标签;
}
}
常数c=新的子项(“子项”);
console.log('c getLabel()='+c.getLabel());//“孩子”
const c1=Object.assign(新的子对象('c1'),c);
c1.标签=‘子修改’;
console.log('c1 getLabel()='+c1.getLabel());//“Child-Modified”
箭头函数使用词法此
。您的对象有一个名为getLabel
的属性,当您调用对象时,该属性会被复制到新的子对象。assign
,该属性包含一个函数,该函数具有对原始父对象的词法引用。如果您使用普通函数而不是箭头函数,您将不会看到这种行为。顺便说一下,super(label)
已经分配了this.label
,因此您不需要this.label=label
@Oriol…谢谢!这是我今天看到的第二个问题,问题是由于使用了箭头函数。我想人们是爱上了它的简单语法,而没有意识到它在行为上有这么大的不同。它对回调函数很好,但对对象方法却不好。@Barmar:这就是我创建它的原因,但它仍然是特定的(例如,它不适合这个用例)。就我个人而言,我希望能够把每一个误用arrow函数的问题都当作一个问题的重复来解决,但这可能只是一厢情愿。