My understanding of this has always been only about being able to use it and knowing it, but I have not delved into its essence. This time, I have a deep understanding with "JavaScript The Good Parts". (All debugging can be seen in the console, browser F12 key)
Let’s take a look at this together.
When we declare a function, each function has two additional parameters (formal parameters) defined, one is this and the other is arguments. arguments are the parameters actually accepted by the function, and are an array of classes. I will only give a brief introduction to arguments, and we will focus on this pointer.
In object-oriented transformation, this is very important, and its value depends on the pattern of the call. In JavaScript, there are 4 calling patterns in total: method calling patterns, function calling patterns, constructor calling patterns, and apply calling patterns.
Method calling mode
When a function is an attribute as an object, we usually call this function a method of this object. When this method is called, this points to the object to which the method belongs.
The code copy is as follows:
<script type="text/javascript">
var people = {
name : "Yika",
sayName : function(){
console.log(this.name); //"Yika"
//This has been bound to the people object
}
}
people.sayName();
</script>
As shown by Chestnut, this points to the sayName object. This method of obtaining the context of the object through this is a public method. (publice method)
Function Call Mode
When a function is called is not a method on an object, it is called as a function.
This pattern call will point to the window object, even if this function may be called in an external function, let's look at it.
The code copy is as follows:
<script type="text/javascript">
var name = "window-Yika";
var people = {
name : "people-Yika",
student : function(){
console.log(this); //This binds the object people here
function saysName(){
var name = "sayName-Yika";
console.log(this.name); //window-Yika
// Even if the sayName function itself and the people object it is located have name value, this points to the window
};
sayName();
}
}
people.student();
</script>
From this perspective, do you know how to solve the JavaScript "design error".
Yes, just cache this in the student function, that is, line 6. Then transfer this to the sayName function through the variables to solve it!
The code copy is as follows:
var people = {
name : "people-Yika",
student : function(){
var self = this; //Cache this
function saysName(){
var name = "sayName-Yika";
console.log(self.name); //"people-Yika", at this time, self points to the people object
};
sayName();
}
}
Constructor call mode
When JavaScript talks about constructors, you will think: "Function name is capitalized! Use the new operator when calling!" Function name capitalization is easy to understand, in order to standardize the naming of the constructor. But have you ever delved into why you need to use new? If you call a new function with new, the function background will create a new object pointing to the function prototype, and this is also bound to the new object. JavaScript is a language based on prototype inheritance. Students who are not very clear about prototype prototypes can check the information by themselves. I focus on this.
Let's first look at what the constructor generally looks like.
The code copy is as follows:
<script type="text/javascript">
function People(name){
this.name = name; //This here points to the new object Yika after calling it with new
this.sayName = function(){
console.log(this.name); //Output
}
}
var Yika = new People("Yika");
Yika.sayName(); //Output "Yika" because Yika is obtained through new call, this is bound to the Yika object.
</script>
At first glance, it seems that it is not easy to understand. Why did this point to the window in the function just now, and now you can point to the People function without cache?
It doesn't matter. Didn't you just say that the function will do "do bad things" secretly by calling new? Let's see what exactly you did.
The code copy is as follows:
<script type="text/javascript">
function People(name){
var that = {}; //Bad thing one: generate an object by yourself
that.name = name;
that.sayName = function(){
console.log(that.name);
};
return that; //Bad thing 2, you will change the behavior of return, return the object that has just been generated
}
var Yika = People("Yika"); //New can be omitted here and imitate the call to the new operator
Yika.sayName(); //Output "Yika" as just now
</script>
You can see clearly this way. New will not only generate an object, but will also automatically return the object, so that this will naturally point to this new object.
Remember to use new to call the constructor, otherwise there will be no warning if something goes wrong, and all capital agreements are still very necessary.
Apply call mode
The apply method allows us to build an array of parameters passed to the calling function, which also allows us to change this value.
function.apply(this bound value, arguments parameter array)
There are so many things that I can say, I will only give you a chestnut here to help you understand:
The code copy is as follows:
<script type="text/javascript">
function People(name){
this.name = name;
this.sayName = function(){
console.log(this.name); //SayName method belongs to the People constructor
}
}
function Student(name){
People.apply(this, arguments);//The integration method of borrowing constructors is to call People constructors by applying in the Student constructor and change this value of People
//In this way, every time a Student instance is created, the People constructor will be called
}
var student = new Student("Yika");
student.sayName(); //Output "Yika"
</script>
We can easily modify the function's this binding object through apply. Call similar to apply also has the same effect. Interested students can search and learn it by themselves.
Okay, finally we have finished changing the four calling modes of this. The method calling mode and constructor calling mode will be used more, and it will be more important. For function calling mode, we must learn to avoid the traps in it.
If there is any error, please report it in time and I will correct it as soon as possible to prevent misleading others. Thank you!