如何在对象构造期间使用异步生成的值分配 属性?

How can a property be assigned during object construction with a value generated asynchronously?

属性如何在对象构造期间分配一个异步生成的值?

我试图在构造期间将 属性 分配给需要通过 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 在回调函数的范围内似乎未定义。

如以下文章 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;
      });
   }
};

引用文章中的有用片段:

Managing this in a callback

And that’s it: those are the four ways to set a function’s this value. Those four rules are not too hard to remember, but there is a common pitfall you should know about. I’m talking about callbacks. It’s easy to be writing a callback and not even know it, like in setTimeout:

setTimeout(function() {
    $(‘button’).addClass(‘red’);
}, 1000);

The setTimeout function accepts a callback, but since it’s not using one of the four rules for setting context, this defaults to the global window object. That’s fine in the example above, but becomes a bug in code like this:

$('button').on('click', function() {
    setTimeout(function() {
        // Uh oh! `this` is the global object!
        $(this).addClass('clicked');
    }, 1000); 
});

We’re expecting $(this) to refer to the button that was clicked, but it doesn’t, since this defaults to the global window object. One way to solve this issue is to store our desired value of this in a local variable and then simply use that variable in a child scope:

$('button').on('click', function() {
    var _this = this;
    setTimeout(function() {
        $(_this).addClass('clicked'); // All better
    }, 1000); 
});

Of course there are many ways to accomplish the same thing. You could use .bind(), .call(), or a number of other options. Choose what works best for each individual situation.