introduce
This plays a very important role in various object programming and is mainly used to point to the calling object. However, in JavaScript, the performance of this is very different, especially in different execution contexts.
From the previous article, we know that this is also an attribute in the execution context, so it is destined to be inseparable from the execution context.
Copy the code code as follows:
activeExecutionContext = {
VO: {...},
this: thisValue};
In Javascript, the value of this depends on the calling mode. There are four calling modes: method calling mode, function calling mode, constructor calling mode and apply calling mode.
call mode
Method calling 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 in the method calling pattern points to the calling object. This is very easy to understand. You are a method of mine, you belong to me, and of course your this points to me.
Copy the code code as follows:
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 the properties or methods in the object through it. As can be seen from the previous article, this, as a member of the attributes in the execution context, must be created when the context is created. All binding of this to the object occurs at the time of the call, which is a "delayed binding". A high degree of reuse of this can be achieved through delayed binding.
Copy the code code as follows:
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"
The function showValue in the above example belongs to delayed binding.
function call pattern
When a function is not called as a method of an object, it is a function call. In function calling mode, this is bound to the global object. (This is a mistake in language design)
Copy the code code as follows:
myObject.double = function(){
var that = this; //Solution
var helper = function(){
console.log(that, ": ", that.value); //Output Object {value: 4, increment: function, double: function} ": " 4
console.log(this, ": ", this.value); //Output Window {top: Window, window: Window…} ": " undefined
}
helper(); //Call as function
}
According to the normal thinking, as output in the fourth line, this should point to the object to which the function belongs. However, due to problems in language design, this points to the global object. This makes this even more mysterious and unpredictable. But as developers, this situation is definitely something we don’t want to see. It’s not common sense to play cards. Fortunately, the remedy is also very simple. In the above example, that is used to refer to this. In this way, calling that in the helper method can be used as this, which is simple and convenient. As for the function calling mode, why this behaves like this will be explained in detail later when analyzing the reference type.
Constructor calling pattern
Since JavaScript is based on prototypal inheritance, its designers want it to be able to create objects through new and constructors like traditional object-oriented languages, realizing object-oriented programming. This doesn't seem to be a good idea, and it's a bit embarrassing to draw a tiger instead of a dog. One is that it is impossible to learn, but there is no need to learn. JavaScript's prototypal inheritance mechanism is already very powerful, enough to meet the inheritance polymorphism required for object-oriented.
Without further ado, let’s talk about the constructor calling pattern. The constructor calling pattern is very simple. It is to use a function as a constructor, and then use this to introduce the properties and methods you intend to make public. as follows
Copy the code code as follows:
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(); //Output name: jink, age: 24
var p2 = new Person("Zhang San", 33);
p2.say();//Output name: Zhang San, age: 33
From the above example, we can clearly see that this points to the object created through new and the constructor. Why is this happening? This is because when the constructor is called through new in JavaScript, the new operator calls the internal [[Construct]] method of the "Person" function, and then, after the object is created, the internal [[Call]] method is called. All the same function "Person" sets the value of this to the newly created object.
apply calling mode
After all functions in JavaScript are created, they will have two methods: apply and call. I don’t want to explain the specific use of these two methods in detail here. Students who don’t know can search on Baidu. It’s quite simple. Through two methods, we can set this manually. Although this is not allowed to be modified during creation, if we manually set it before creation, that is another matter. This setting is amazing, you can make your object call any method, just like you can make a car sail in the sea, an African elephant speed like a jaguar, and a programmer play like a pianist. Haha, imagination is always beautiful. Calling is calling, but whether the function can be realized after calling is another matter.
Copy the code code as follows:
var programmer = {
name: "Programmer",
hand: "flexible hands",
program : function(){
console.log(this.name+"Write code with "+this.hand+".");
}
}
var pianist = {
name: "pianist",
hand: "flexible hands",
play : function(){
console.log(this.name+"Play beautiful music with "+this.hand+".");
}
}
var player = {
name: "athlete",
foot: "Strong legs",
run : function(){
console.log(this.name+"Use "+this.foot+" to run on the field.");
}
}
//Follow the rules
programmer.programme(); //Programmers write code with flexible hands.
pianist.play(); //The pianist uses his flexible hands to play beautiful music.
player.run(); //Athletes run on the field with strong legs.
//whimsical
pianist.play.apply(programmer); //Programmers use their flexible hands to play beautiful music.
player.run.apply(programmer); //Programmers use undefined to run on the field. Due to lack of physical exercise, I don’t have strong legs
It seems interesting to see above. The first parameter of apply is the this pointer in the execution method. In this way, we can borrow other people's methods and use them secretly ourselves, which is extremely convenient. This type of technique is often used in some frameworks.
Summarize
That’s all I have to say about this. I believe that after reading this, everyone will have some understanding of the determination of this in different situations. I originally planned to discuss the reference object next and explain the value of this in the method calling mode and function calling mode. principle, but I was afraid that the length would be too long, so I decided to use a separate chapter to analyze the concept of reference objects.