【问题标题】:How to get parent class from inner var in Javascript?如何从Javascript中的内部变量获取父类?
【发布时间】:2018-08-03 15:00:03
【问题描述】:

我有这样的课

class Game {
    constructor(player1, player2, gameId) {

        this.Clockk = {
            totalSeconds: timeForAnswer,
            nowSeconds: timeForAnswer,

            start: function () {
                var self = this;
                this.interval = setInterval(function () {
                    self.nowSeconds -= 1;
                    if (self.nowSeconds == 0) {

                          here I want to call "answered" function

                    }
            },

            reset: function(){
                this.nowSeconds = this.totalSeconds;
            },
        };

        answered(player) {
             console.log(player);
        }
    };

我想从this.Clockk 变量中调用Game 类的函数。 变量中的this 关键字是this.Clockkitself,我怎样才能获得父类本身?

【问题讨论】:

  • 该代码至少有几个语法错误,您能否将其改正(除了您不知道如何进行的调用),因此我们不会猜测您想要做什么?
  • 如果你有像const myGame = new Game(); 这样的代码,那么像myGame.answered(); 这样的代码就可以了。但是在更好的结构中,时钟和游戏不会以这种方式相互耦合:游戏可以将回调传递给时钟,一旦时钟达到零,该回调就会被触发。然后游戏运行时钟而不是时钟运行部分游戏。
  • 您可以使用箭头函数来保留 this 上下文,但我经常发现那里的灵活性不如您已经做过的那样 -> var self = this; 但是要使它更健壮,您可以这样做 @987654329 @,你可以为你的游戏做另一个,所以你的构造函数的第一行做var thisGame = this,现在你想引用什么this没有混淆。

标签: javascript node.js web browser


【解决方案1】:

如果您在 Clockk 对象的方法中,则 this 将引用 Clockk 对象,并且在 Javascript 中,没有自然的方式来引用“父”或“包含”对象.因此,您必须在某处存储对父级的引用。我可以想到两种直接存储它的方法。一种是存放在父作用域中,另一种是存放在Clockk对象本身的实例数据中。

仅供参考,我还假设 answered() 方法应该是 Game 对象上的方法(您问题中的代码并没有完全表明这一点 - 但这似乎是意图)。

这里有两种方法可以使用this.Clockk.start() 方法调用父级的answered() 方法:

在父作用域中保存父引用

class Game {
    constructor(player1, player2, gameId) {

        // save parent reference here so child scopes can refer to it
        let parentObj = this;

        this.Clockk = {
            totalSeconds: timeForAnswer,
            nowSeconds: timeForAnswer,

            start: function () {
                var self = this;
                this.interval = setInterval(function () {
                    self.nowSeconds -= 1;
                    if (self.nowSeconds == 0) {

                        // here I want to call "answered" function
                        parentObj.answered();

                    }
            },

            reset: function(){
                this.nowSeconds = this.totalSeconds;
            },
        };

    }
    answered(player) {
        console.log(player);
    }
}

将父引用保存在Clockk 实例数据中

class Game {
    constructor(player1, player2, gameId) {

        this.Clockk = {
            // save parent reference in our own instance data
            parent: this,     
            totalSeconds: timeForAnswer,
            nowSeconds: timeForAnswer,

            start: function () {
                var self = this;
                this.interval = setInterval(function () {
                    self.nowSeconds -= 1;
                    if (self.nowSeconds == 0) {

                        // here I want to call "answered" function
                        self.parent.answered();

                    }
            },

            reset: function(){
                this.nowSeconds = this.totalSeconds;
            },
        };

    }
    answered(player) {
        console.log(player);
    }
}

或者,您可以将 Clockk 实现分解为它自己的 class 定义,然后在其构造函数中将父级传递给它,然后其构造函数会将父级引用存储在它自己的实例数据中。

【讨论】:

  • +1 表示努力,只是希望他们为Clock 创建一个单独的类,而不是将其声明嵌套在另一个类的构造函数中。
  • @PatrickRoberts - 嵌套有一些优点,例如我展示的第一个选项只能在嵌套时使用。但是,我总体上理解并同意您的评论。在这种情况下,您可能会在创建 Clockk 对象时将父对象传递给构造函数。
  • @Bakurits 分离类具有更少的“代码气味”并提供更多优化,因为Clock 的成员方法可以共享,而不是为Game 的每个实例重新声明。只是我的两分钱。
  • @PatrickRoberts - 我不反对,但我们可以在这里保持话题吗?这不是这个问题的目的。
猜你喜欢
  • 2011-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多