在位于同一类中的对象中的方法内部引用类局部变量

时间:2018-10-10 06:34:07

标签: javascript ecmascript-6

这是示例代码。

class TestClass {
    constructor() {
        let question = "How could I refer this variable inside of the nested object?"
    }
}

TestClass.prototype.category = {
    validate : function () {
        return true;
    }
    , read : function () {
        // this in here is not TestClass. How could I refer TestClass Instance(caller) in strict mode ?
        console.log('Inside of TestClass.prototype.category.read', this);
        if(this.validate) {
            console.log('I would like to refer TestClass.question', this.question);
        }
    }
}

TestClass.prototype.readCategory = function () {
    this.category.read();
}

然后,我在chrome编辑器控制台中执行以下操作。

var test = new TestClass();
test.readCategory();

// result is like below
I would like to refer TestClass.question undefined

据我所知,我想像

  1. 使用new关键字时,我将生成一个包含question变量和推入prototype的方法的实例
  2. 然后它将执行readCategory(),并调用instance.category.read,但此时,this关键字将指向instance.read对象,而不是TestClass实例。因此this.question将是一个undefined值。
  3. 所以这是问题,我怎么能访问调用者(或Class实例)变量?

我发现当我们使用class时,无法使用this.caller。(自动应用严格模式)。

在这种情况下如何访问类变量?谢谢。

1 个答案:

答案 0 :(得分:0)

不能,您的category变量是构造函数完全私有的。构造函数返回后,它就消失了。

您的结构是相当不寻常的,但是如果您确实需要category作为从属对象,但是仍然希望它可以访问它的一部分TestClass实例,则可以使用创建的箭头函数在构造函数中实现该目标,请参见注释:

class TestClass {
    constructor() {
        // Make question a property
        this.question = "How could I refer this variable inside of the nested object?"
        // Make category an instance property using arrow functions
        this.category = {
            validate : () => {
                return true;
            }
            , read : () => {
                console.log('Inside of TestClass.prototype.category.read', this);
                if(this.category.validate()) { // <=== Need to add `category.` and `()`
                    console.log('I would like to refer TestClass.question', this.question);
                }
            }
        };
    }

    // No reason to define this outside the `class` construct, make it a method
    readCategory() {
        this.category.read();
    }
}

使用class fields proposal(当前处于阶段3,因此您需要进行转译),也可以这样编写:

class TestClass {
    // Make category an instance property using arrow functions
    category = {
        validate : () => {
            return true;
        }
        , read : () => {
            console.log('Inside of TestClass.prototype.category.read', this);
            if(this.category.validate()) { // <=== Need to add `category.` and `()`
                console.log('I would like to refer TestClass.question', this.question);
            }
        }
    };

    constructor() {
        // Make question a property
        this.question = "How could I refer this variable inside of the nested object?"
    }

    // No reason to define this outside the `class` construct, make it a method
    readCategory() {
        this.category.read();
    }
}

这实际上与第一个示例相同;字段初始化程序就像在构造函数中一样执行。

如果您不希望question成为实例的属性,因为这些是构造函数中定义的箭头函数,则可以将其保留为它们封闭的局部变量:

class TestClass {
    constructor() {
        let question = "How could I refer this variable inside of the nested object?"

        this.category = {
            validate : () => {
                return true;
            }
            , read : () => {
                console.log('Inside of TestClass.prototype.category.read', this);
                if(this.category.validate()) {
                    console.log('I would like to refer TestClass.question', question); // <== No `this.`
                }
            }
        };
    }

    readCategory() {
        this.category.read();
    }
}