javascript - JS : Rebound "this" in contextless function call

标签 javascript function function-binding

这个例子中的函数 doSomethingElse 执行失败,因为它的 this 已经被重新绑定(bind)到 windowglobal (如果在 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/

相关文章:

javascript - 如何使用 jQuery 使某些单选按钮强制使用文本框?

javascript - 使用 AJAX 自动刷新内容

jquery - 等待其他函数中的动画完成

c++ - 关于传递给函数后指针重用的问题

typescript - 使用绑定(bind)时强制输入

reactjs - JSX Prop 不应使用 .bind()

javascript - 在带有 JavaScript 的普通 HTML 页面中使用 GitLab 变量

javascript - 如何将 Node 编译的 JavaScript 输出(字节代码)保存到单独的文件中

javascript - jQuery 日期选择器 : Prevent closing picker when clicking a date

javascript - Function.bind.bind(Function.call) 如何取消柯里化(Currying)?