我正在构建一个在游戏引擎和编辑器之间共享的类。我想在编辑器中定义一些属性和方法,而不是引擎,所以我写了以下代码
class Asset{
constructor(){
this.prop1 = 1;
}
}
if (window.IS_EDITOR){
Asset.prototype.editorProp = 2;
}
class Room extends Asset{
constructor(){
super();
this.prop2 = 3;
console.log(this)
//expected: {prop1: 1, prop2: 3, editorProp: 2}
//what I get: {pro1: 1, prop2: 3}
}
}
我基本上只是想有条件地向建构式添加另一个属性,但我很困惑为什么editorProp
在我访问this
.
uj5u.com热心网友回复:
因为它在您物件的原型上,就像.constructor
, 并且默认情况下不会打印console.log
。如果您展开原型,或者您将console.log(Object.getPrototypeOf(this))
. 您仍然可以像this.editorProp
预期值一样访问它,因为它是继承的。
如果要在建构式中将属性添加到实体中,则实际上应该在建构式中进行:
class Asset {
constructor() {
this.prop1 = 1;
if (window.IS_EDITOR) {
this.editorProp = 2;
}
}
}
uj5u.com热心网友回复:
就像指出的那样,console.log
只是记录物件,而不是原型链中的内容。这样做console.log(this.editorProp)
确实会回传2
,因为现在使用了原型链。
如果你想看到原型变平的物件,使用in
. 在下面的示例中,我添加了一个简单的函式flat
来执行此操作。
同样值得注意的是,向类添加方法将使它们自动成为不可列举的,但是如果向原型添加方法,它将是可列举的。所以下面的一个例子我还添加了一个被呼叫的函式,fn
但defineProperty
用来阻止它是可列举的。
window.IS_EDITOR = true;
class Asset{
constructor(){
this.prop1 = 1;
}
}
if (window.IS_EDITOR){
Asset.prototype.editorProp = 2;
//adding a function this will will be
//enumerable, so you might want to use
//defineProperty here.
Object.defineProperty(
Asset.prototype,
'fn',
{value: () => {console.log('fn called')}, enumerable: false});
}
class Room extends Asset{
constructor(){
super();
this.prop2 = 3;
console.log(this.flat());
this.fn();
//expected: {prop1: 1, prop2: 3, editorProp: 2}
//what I get: {pro1: 1, prop2: 3}
}
flat() {
const ret = {};
for (const i in this) ret[i] = this[i];
return ret;
}
}
new Room();
0 评论