JavaScript function binding (this keyword) is lost after assignment

前端 未结 5 799
甜味超标
甜味超标 2020-11-30 12:28

this is one of most mystery feature in JavaScript, after assigning the object method to other variable, the binding (this keyword) is lost

var john = {
  nam         


        
5条回答
  •  我在风中等你
    2020-11-30 13:33

    john.greet("Mark") actually calls a function. When you do var fx = john.greet;, you're getting a reference to the function. So when you call it, this is not bound to john. What you're actually doing is window.fx("Mark") and so this is the window object. You were on the right track when you said that it was in the global context. In this particular instance, the global object is window, and so fx is actually window.fx.

    When you have a function reference you should use call or apply if you want to set the value of this. Try doing this:

    fx.call(john, "Mark");
    

    The first argument in call or apply is the value used for this in the context of the function call.

    EDIT

    Some people mentioned that the real issue here might be confusion surrounding an object literal vs. an instance of an object. You're creating an object literal which also behaves kind of like a singleton. You cannot create a new instance of that object. In this case john is a reference to that object literal. In that context, this in the function greet refers to the object literal itself. Hence when you call john.greet("Mark"), this is bound to john.

    When you grab a reference to john.greet just by itself and assigning it to a global variable, you're essentially doing this:

    var fx = function(person) {
       alert("Hi " + person + ", my name is " + this.name);
    }
    

    In this scenario, this is window, because fx is basically window.fx (since the global object here is window. Assuming this code was wrapped inside another function, then the global object would refer to that function.

    If you want to create multiple instances of an object, you can do something like this:

    var Person = function(name) {
        var self = this; //maintains a reference to the instance
    
        this.name = name;
        this.greet = function(name) {
            alert("Hi " + name + ", my name is " + self.name);
        }
    }
    
    var john = new Person("John");
    john.greet("Mark"); // alerts "Hi Mark, my name is John"
    
    var fx = john.greet;
    fx("Mark"); // also alerts "Hi Mark, my name is John"
    

    Here, the self variable (which is local to the function) maintains a reference to the actual instance because you're binding it to this when you create the object.

    There are many best practices associated with OOP in Javascript. You can Google and find out (there are many links). I recommend reading stuff from Douglas Crockford especially.

提交回复
热议问题