'this' being scoped to window object when

2019-06-03 22:49发布

I'm not sure if the title to this makes any sense, but essentially I am trying to write a very simple Javascript dependency injection container for an app I am working on.

This is the container:

jedi = new function() {
    var library = {};

    this.module = function(name, module) {
        if (arguments.length == 1) {
            return library[name];
        }

        library[name] = module;
    };
};

I then create a Backbone model and add it as a dependency like so:

(function () {

    var addColourSchemeModel = Backbone.Model.extend({
        getColourJSON: function(prop) {
            var cols = this.get(prop).split(',');
            return {
                R: cols[0],
                G: cols[1],
                B: cols[2]
            };
        }
    });

    jedi.module('AddColourSchemeModel', addColourSchemeModel);

})();

The problem occurs when I try to create a new instance of this module like so:

var colourModel = new jedi.module('AddColourSchemeModel')({
    // json object containing model values
});

I get an error Object [object global] has no method 'set'.

The strange thing is the Backbone Model initialize methods etc are being called, but this is being scoped to the window instead of the object being initialized, this is where the error is ocurring as it is trying to call this.set at some point but this is actually the window.

2条回答
SAY GOODBYE
2楼-- · 2019-06-03 23:07

You need to put jedi.module('AddColourSchemeModel') in parentheses, when creating an instance. Otherwise you code will be interpreted as:

var colourModel = (new jedi.module('AddColourSchemeModel'))({
    // json object containing model values
});

So the right way should be:

var colourModel = new (jedi.module('AddColourSchemeModel'))({
    // json object containing model values
});
查看更多
你好瞎i
3楼-- · 2019-06-03 23:21

This is all because of how javascript does the binding for 'this', the context when executing a all. It causes initial confusion for people from other different background. Getting Out of Binding Situations in JavaScript provided excellent explanation on what you are seeing. There are various techniques to address this :-)

Here are a few articles that may help,

Hope this help.

查看更多
登录 后发表回答