首页 > 解决方案 > 在位于同一类的对象中的方法内引用类局部变量

问题描述

这是示例代码。

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,无法使用this.caller。(自动应用严格模式)。

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

标签: javascriptecmascript-6

解决方案


你不能,你的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();
    }
}

使用类字段提案(目前处于第 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();
    }
}

推荐阅读