我正在Chrome Canary 63和Chrome 61上测试以下代码.代码的目标是设置一个将super调用到类实例(z)的方法.在我的代码库中,有时会在添加到实例之前使用Object.assign克隆属性块,并且只要发生这种情况,代码就会失败.
我用下面的代码示例重现了这个问题.如果避免浅层克隆(props = Object.assign({},props);)代码工作正常但是如果我添加该行我得到TypeError :(中间值).bar不是一个函数.
我已经尝试过Object.create(this,Object.getOwnPropertyDescriptors(props))而不是Object.assign,但它会导致相同的错误.
有没有办法在已克隆的对象上正确设置super?
let Moo = class {
bar() {
return " [bar on Moo] ";
}
};
let Zoo = class extends Moo {
bar() {
return " [bar on Zoo] " + super.bar();
}
};
function addProps(inst,props) {
// Code works if the line below is commented out but otherwise
// results in TypeError: (intermediate value).bar is not a function
props = Object.assign({},props); // <-- Offending code
Object.setPrototypeOf(props,inst.__proto__);
Object.assign(inst,props);
}
let props = {
onZooInst: {
bar() {
return " [bar on overridden instance] " + super.bar();
}
}
};
let z = new Zoo();
addProps(z,props.onZooInst);
console.log(z.bar());
最佳答案
Is there any way to properly set
super
on objects that have been cloned?
不. super使用函数的[[HomeObject]]插槽,该插槽在创建功能(方法)时设置,目前无法更改.
可能来自规范的最佳报价是在Table 27:
[[HomeObject]]
: If the function usessuper
,this is the object whose [[GetPrototypeOf]] provides the object wheresuper
property lookups begin.
你唯一能做的就是尝试改变函数的[[HomeObject]]引用的对象的原型,但是A)快速变得丑陋,B)杀死性能(在那些重要的情况下).