How can I maintain control of the this keyword whe

2019-03-01 04:13发布

问题:

This question already has an answer here:

  • How to access the correct `this` inside a callback? 10 answers

I'm implementing a class-like structure in jQuery, but I'm having some trouble when I try to call some of my functions.

This is how the structure is setup:

MyClass = function(name) {
    this.init(name);
}
$.extend(MyClass.prototype, {
    init: function(theName) {
        this.myFunction(); // works
        $('.myclass').each(function(){
            this.myFunction(); // doesn't work
        });
    },
    myFunction = function(){}
});

The problem I'm having is that when I try to call one of my functions (e.g., myFunction()) from inside a jQuery block (like the each() construct above), I get the error "myFunction() is not a function."

I think this has something to do with the this keyword changing its meaning inside the jQuery block, but I'm not sure. Any help would be appreciated!

回答1:

You need to assign this to another variable, because of how scope works.

MyClass = function(name) {
    this.init(name);
}
$.extend(MyClass.prototype, {
    init: function(theName) {
        this.myFunction(); // works
        var that = this;
        $('.myclass').each(function(){
                this.myFunction(); // doesn't work
                that.myFunction(); // should work
        });
    },
    myFunction = function(){}
});


回答2:

The .each() function changes the context of this (as does any function in JavaScript).

You need to do something like this:

MyClass = function(name) {
    this.init(name);
}
$.extend(MyClass.prototype, {
    init: function(theName) {
        this.myFunction(); // works
        var myClass = this;
        $('.myclass').each(function(){
                myClass.myFunction(); // doesn't work
        });
    },
    myFunction = function(){}
});


回答3:

MyClass = function(name) {
    this.init(name);
}
$.extend(MyClass.prototype, {
    init: function(theName) {
        this.myFunction(); // works
        temp = this;
        $('.myclass').each(function(){
                temp.myFunction(); // works
        });
    },
    myFunction = function(){}
});

Try that. :)