如何在对象构造期间使用异步生成的值分配属性?
我正在尝试在构造期间将属性分配给需要通过AJAX检索的对象:
//define module prototype
Library.Module = function () {
this.resources = {};
for (var i = 0; i < arguments.length; i++) {
// assume that Library.require makes a request and
// then executes this callback
Library.require(arguments[i], function (resource) {
// ! the problem seems to be that 'this' is undefined
// in the scope of the callback
this.resources[resource.location] = resource;
});
}
};
我认为这段代码的意图相当明确 - 问题是this
似乎在回调函数的范围内未定义。
答案 0 :(得分:1)
如下面的文章https://blog.engineyard.com/2015/mastering-this-in-javascript和后面的评论中所述,可能的解决方案是将其存储在范围中较高的变量中,以便在回调中使用它。
因此可能的解决办法是:
Library.Module = function () {
var _this = this;
_this.resources = {};
for (var i = 0; i < arguments.length; i++) {
// assume that Library.require makes a request and
// then executes this callback
Library.require(arguments[i], function (resource) {
_this.resources[resource.location] = resource;
});
}
};
引用文章中的有用摘录:
在回调中管理
就是这样:这是设置函数的四种方法。 这四条规则并不难记,但有一个共同点 你应该知道的陷阱。我在谈论回调。这很简单 写一个回调,甚至不知道它,就像在setTimeout中一样:
setTimeout(function() { $(‘button’).addClass(‘red’); }, 1000);
setTimeout函数接受回调,但因为它没有使用 设置上下文的四个规则之一,默认为全局 窗口对象。在上面的例子中这很好,但是变成了一个bug 像这样的代码:
$('button').on('click', function() { setTimeout(function() { // Uh oh! `this` is the global object! $(this).addClass('clicked'); }, 1000); });
我们期望$(this)引用被点击的按钮,但是 它没有,因为它默认为全局窗口对象。单程 解决这个问题的方法是将我们想要的值存储在本地 变量,然后简单地在子范围中使用该变量:
$('button').on('click', function() { var _this = this; setTimeout(function() { $(_this).addClass('clicked'); // All better }, 1000); });
当然,有很多方法可以完成同样的事情。你可以 使用.bind(),. call()或许多其他选项。选择有效的方法 最适合每个人的情况。