拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 无法访问通过原型添加的属性,在Javascript中使用“this”

无法访问通过原型添加的属性,在Javascript中使用“this”

白鹭 - 2022-02-22 1936 0 0

我正在构建一个在游戏引擎和编辑器之间共享的类。我想在编辑器中定义一些属性和方法,而不是引擎,所以我写了以下代码

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来执行此操作。

同样值得注意的是,向类添加方法将使它们自动成为不可列举的,但是如果向原型添加方法,它将是可列举的。所以下面的一个例子我还添加了一个被呼叫的函式,fndefineProperty用来阻止它是可列举的。

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 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *