【问题标题】:JS: Rebound "this" in contextless function callJS:在无上下文函数调用中反弹“this”
【发布时间】:2019-02-13 06:53:19
【问题描述】:

由于app.populateDatabase 内部的无上下文调用,此示例中的函数doSomethingElse 无法执行,因为它的this 已被重新绑定到windowglobal(如果在Node 中)。

有没有办法避免这种情况而不在每个函数中引用app

loadDatabase函数根据逻辑语句执行回调,如果虚构的数据库不存在,加载后填充,然后populateDatabase执行已提供的回调。

我无法将onLoaded 参数重新绑定到app,因为我不知道它来自哪里,并且过度使用绑定/应用/调用抽象会造成相当混乱。

var app = {};
app.loadDatabase = function(onLoaded) {

    // If database already exists, only run a callback
    var callback = onLoaded;

    // If database doesn't exists, populate it, then run a callback.
    if (!databaseExists) {
        callback = this.populateDatabase.bind(this, onLoaded);
    }

    this.database = new sqlite.Database("file.db", function(error) {
        if (error) { ... }

        callback();
    })

}

app.populateDatabase = function(onPopulated) {

    // Contextless call here. <--------
    onPopulated();
}

app.doSomethingElse = function() {

    // this != app due to contextless call.
    this.somethingElse();
}

app.run = function() {

    // Load the database, then do something else.
    this.loadDatabase(this.doSomethingElse);
}

app.run();

【问题讨论】:

  • 然后使用 ES6 箭头函数(它们自己没有 this)。
  • @connexo 这到底有什么帮助?我使用this 来引用app 而没有实际命名它。
  • 这意味着该函数将具有在调用之外可用的this
  • 另一种选择是将.bind(app) 添加到您希望this 始终指向app 的任何函数定义中。

标签: javascript function function-binding


【解决方案1】:

只需将this.loadDatabase(this.doSomethingElse); 替换为this.loadDatabase(() =&gt; this.doSomethingElse());。这样您就可以创建一个新的箭头函数,但随后会使用正确的 this 上下文调用 doSomethingElse

您也可以使用.bind,但我推荐使用箭头功能。这里有bindthis.loadDatabase(this.doSomethingElse.bind(this))


一般考虑转向 Promise 和异步函数。然后这样做:

this.loadDatabase().then(() => this.doSomethingElse());

或者更好的异步函数:

await this.loadDatabase();
this.doSomethingElse();

【讨论】:

  • 在这种情况下,箭头函数应该返回函数的值而不是函数本身。 this.loadDatabase(() =&gt; this.doSomethingElse):传递的参数是一个箭头函数,它返回对doSomethingElse 的引用。 this.loadDatabase(() =&gt; this.doSomethingElse()):传递的参数是一个箭头函数,调用doSomethingElse并返回返回值。
  • 是的。对不起,我更正了。在这种情况下随意编辑;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
相关资源
最近更新 更多