JS:在无上下文函数调用中反弹“this”

问题描述 投票:1回答:1

此示例中的函数doSomethingElse无法执行,因为this由于window内部的无上下文调用而被反弹到globalapp.populateDatabase(如果在Node中)。

有什么办法可以避免这种情况而不引用每个函数中的app吗?

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

我无法将onLoaded参数重新绑定到app,因为我不知道它来自何处,而bind / apply / call抽象过度使用会造成很多混乱。

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();
javascript function function-binding
1个回答
3
投票

this.loadDatabase(this.doSomethingElse); 替换this.loadDatabase(() => this.doSomethingElse());。这样你就可以创建一个新的箭头函数,然后使用正确的doSomethingElse上下文调用this

你也可以做.bind,但我推荐箭头功能。在这里与bindthis.loadDatabase(this.doSomethingElse.bind(this))


一般来说,考虑转向承诺和可能是异步功能。然后这样做:

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

或者更好的异步功能:

await this.loadDatabase();
this.doSomethingElse();
© www.soinside.com 2019 - 2024. All rights reserved.