Javascript on this

  • 2020-03-30 00:58:36
  • OfStack

introduce
This plays a very important role in a variety of opposition object programming, mainly used to point to the calling object. However, in JavaScript, the performance of this varies greatly, especially from execution context to execution context.

As we know above, this also belongs to an attribute in the execution context, so it is doomed to be related to the execution context.


activeExecutionContext = {
VO: {...},
this: thisValue};

In Javascript, the value of this depends on the mode of invocation. There are four modes of invocation: method invocation, function invocation, constructor invocation, and apply invocation.

Invocation pattern
Method invocation pattern
When a function is saved as a property of an object, we call it a method. When a method is called, this is bound to the object, that is, this points to the calling object in the method call mode. This is very easy to understand, you are one of my methods, you belong to me, your this of course points to me.


var myObject = {
        value : 0,
        increment : function(inc) {
             this.value += typeof inc === "number" ? inc : 1;
       }    
}    
myObject.increment();
console.log(myObject.value);  //Output: 1.
myObject.increment(3);
console.log(myObject.value);   //Output: 4

Because you can access the object you belong to through this, you can call and modify properties or methods in the object through it. As can be seen from the above, as a member of the properties in the execution context, this must be created when the context is created, and all the bindings of this to the object occur at the time of invocation, which belongs to "delayed binding". This is highly reusable through deferred binding.


function showValue(){
        console.log(this.value);  
}
var a = { value : "a"};
var b = { value : "b"};
a.showValue = showValue;
b.showValue = showValue;
a.showValue();  //Output "a"
b.showValue();  //Output "b"

In the example above, the function showValue is a delayed binding.

Function call pattern
A function is called when a function is not called as a method of an object. In function call mode, this is bound to a global object. (this is a language design error)


myObject.double = function(){
    var that = this;   //The solution
    var helper = function(){
        console.log(that, ": ", that.value); //Output Object {value: 4, increment: function, double: function} ": "4
        console.log(this, ": ", this.value); //The output   Window {top: Window, Window: Window... } ":" undefined
    }

    helper(); //Called as a function
}

Normally, this points to the object to which the function belongs, as shown in the fourth line, but this points to the global object because of the language design problem above. This makes this even more mysterious and elusive. But as developers, this is certainly something that we don't want to see, to play by the rules and this is, thankfully, the remedy is very simple, which is that for this. This way, calling that in a helper method can be used as this, which is simple and convenient. As to why this is the case in the function call pattern, this will be explained later in the analysis of reference types.

Constructor invocation pattern
Since javascript is based on prototype inheritance, but its designers wanted it to be able to create objects with new and constructors like traditional object-oriented languages, real object-oriented programming. This does not seem to be a good idea, there is a tiger painting is not anti-dog embarrassment. One is not to learn, but there is no need to learn. Javascript's prototype inheritance mechanism is already powerful enough to satisfy the inheritance polymorphism required for object orientation.

Without further ado, let's get back to the constructor invocation pattern. Constructor call mode this is very simple, it is a function as the constructor, and then you intend to public the properties and methods with this declaration. The following


function Person(name, age){
        this.name = name;
        this.age = age;
        this.say = function(){
            console.log("name : %s, age : %n", this.name, this.age);
       }
}
var p1 = new Person("jink", 24);
p1.say(); //The output   Name: jink, age: 24
var p2 = new Person(" Zhang SAN ", 33);
p2.say();//The output   Name: zhang SAN, age: 33

As you can see from the above example, this refers to objects created through new and constructors. Why is that? This is because in javascript, when the constructor is called through new, the new operator calls the inner [[Construct]] method of the "Person" function, and then, after the object is created, the inner [[Call]] method. All the same function "Person" sets the value of this to the newly created object.

Apply invocation pattern
After all the functions in javascript are created, there are two methods: apply and call. The specific use of these two methods, I do not want to elaborate here, do not know the students can baidu, quite simple. With two methods, we can set this manually. Although this is not allowed to be modified at the time of creation, we set it manually before creating it, which is another matter. With this setup, you can make your object call any method, just as you can make a car sail in the ocean, Africa fly like a jaguar, and a programmer play like a pianist. Ha ha imagination is always good, call call, but call can achieve the function on the other side.


var programmer = { 
    name : " The programmer ",
    hand : " Flexible hands ", 
    programme : function(){ 
        console.log(this.name+" with "+this.hand+" Write code. ");
    }
}
var pianist = { 
    name : " The pianist ",
    hand : " Flexible hands ", 
    play : function(){ 
        console.log(this.name+" with "+this.hand+" Play beautiful music. ");
    }
}
var player = { 
    name : " athletes ",
    foot : " Good legs ", 
    run : function(){ 
        console.log(this.name+" with "+this.foot+" Racing around the track. ");
    }
}
//conventional
programmer.programme(); //Programmers write code with flexible hands.
pianist.play(); //The piano USES flexible hands to play beautiful music.
player.run(); //The athletes galloped on the field with their strong legs.
//whimsical
pianist.play.apply(programmer); //Programmers use flexible hands to play beautiful music.
player.run.apply(programmer); //The programmer USES undefined to run around the track.     Due to the lack of their own movement, no vigorous legs

The first parameter to apply is to execute the this point in the method. In this way, we can borrow other people's methods to secretly use their own, is extremely convenient. This technique is commonly used in some frameworks.

conclusion
Said about this is so much, I believe you have seen, in a different context this judgement are learned, had intended to discuss the following discussion of the reference object, describe the method model and function calls in the principle of this value, but afraid of length is too long, so I decided to use a separate chapter to analyze the reference object this concept.


Related articles: