这个例子中的函数 doSomethingElse
执行失败,因为它的 this
已经被重新绑定(bind)到 window
或 global
(如果在 Node 中)由于 app.populateDatabase
中的无上下文调用。
如果不在每个函数中引用 app
有没有办法避免这种情况?
loadDatabase
函数根据逻辑语句执行回调,如果一个假想的数据库不存在,加载后填充它,然后 populateDatabase
执行回调它已提供。
我无法将 onLoaded
参数重新绑定(bind)到 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();
最佳答案
只需替换 this.loadDatabase(this.doSomethingElse);
与 this.loadDatabase(() => this.doSomethingElse());
。通过这种方式,您可以创建一个新的箭头函数,然后使用正确的 this
上下文调用 doSomethingElse
。
你也可以做 .bind
但我推荐箭头函数。这里使用 bind
:this.loadDatabase(this.doSomethingElse.bind(this))
通常考虑转向 promises 和异步函数。然后这样做:
this.loadDatabase().then(() => this.doSomethingElse());
或使用异步函数更好:
await this.loadDatabase();
this.doSomethingElse();
关于javascript - JS : Rebound "this" in contextless function call,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52230665/