Master "this" in JS (2)
In the previous article, master the"this
(1) We learned how to correctly usethis
Keyword and its basic principle. We also know the decisionthis
The key factor pointing to an object is to find the current execution context ). However, if the execution context is not set in the normal way, the problem may become very difficult. In this article, I will focus on the areas where this happens and how it can be done.
Solve common problems
In this section, we will explore some of the most common problems when using the this keyword and learn how to handle this situation.
1. Use the Extracted method
this
The most common error is to assign an object method to a variable and considerthis
Still pointing to the original object. We can see from the example below that this is not the case at all.
var car = { brand: Nissan, getBrand: function(){ console.log(this.brand); }};var getCarBrand = car.getBrand;getCarBrand(); // output: undefined
Looks likegetCarBrand
It seems that the reference iscar.getBrand()
But what he actually points to isgetBrand()
Itself. We already know that the most important thing to determine the context is the call-site. In the above Code, the call point isgetCarBrand()
This is just a common function call.
ProofgetCarBrand
To point to a common function (baseless function, which is not bound to any function of a specific object ),alert(getCarBrand);
To view the corresponding content. The alert output is as follows:
function(){ console.log(this.brand);}
getCarBrand
It is just a common function, and it is no longercar
Object method. Therefore, in this case,this.brand
Will be convertedwindow.brand
. Of course, the output result isundefined
.
If we remove (extract) A method from an object, this method will become a common function ). He and the original object are disconnected (severed), so they no longer run in the original way. In other words, a split function is no longer bound to the original object.
How can this problem be solved? OK. If you want to point to the original object, you must assign a valuegetCarBrand
ExplicitlygetBrand()
Function binding (bind)car
Object. Of course, we can use the bind () method.
var getCarBrand = car.getBrand.bind(car);getCarBrand(); // output: Nissan
Now we get the expected correct output because we have successfully redefined the desired context.
2. Use in the callback function
this
The second type of problem isthis
) Method as the callback function. For example:
View car brands
var car = { brand: Nissan, getBrand: function(){ console.log(this.brand); }};var el = document.getElementById(btn);el.addEventListener(click, car.getBrand);
Althoughcar.getBrand
, But in fact, onlygetBrand()
Function associatedbutton
Object.
Passing a parameter to a function is an implicit value assignment, so this is basically the same as the previous example. The difference is thatcar.getBrand
No explicit value assignment. The result is the same. The result is only a common function, and the bound object isbutton
.
In other words, when we execute a method on an object, although this method may be defined in other objectsthis
The keyword no longer points to the original object, but to the object that calls this method.
For example, in the preceding example, we useel
(That is, button) to executecar.getBrand
Is useless.car
Object, although initially defined incar
Object. Therefore,this
Pointel
Insteadcar
.
If you do need to retain reference to the original object, you need to explicitlygetBrand()
Function bindingcar
Object, which can be used by each functionbind()
Method.
el.addEventListener(click, car.getBrand.bind(car));
Now, you can run it as needed.
3. Use in Closure
this
Use in closuresthis
It may also cause errors. See the following example:
var car = { brand: Nissan, getBrand: function(){ var closure = function(){ console.log(this.brand); }; return closure(); }};car.getBrand(); // output: undefined
Here, the output isundefined
Because the closure function (internal function) cannot access the external Functionthis
Variable. So the final result isthis.brand
Equivalentwindow.brand
Becausethis
The bound global object.
To solve this problem, we canthis
BindgetBrand()
Function.
Var car = {brand: Nissan, getBrand: function () {var closure = function () {console. log (this. brand );}. bind (this); // pay attention to return closure () ;}}; car. getBrand (); // output: Nissan
The binding here is equivalentcar.getBrand.bind(car)
.
Another common method for processing closures is to firstthis
Assign values to another variable to avoid unnecessary changes.
var car = { brand: Nissan, getBrand: function(){ var self = this; var closure = function(){ console.log(self.brand); }; return closure(); }};car.getBrand(); // output: Nissan
Here, we can assign the _ this value_this
,that
,self
,me
,my
,context
Or other variable names with such meanings. The key is to keep the object reference of the lower outer layer.
High technology in ECMAScript 6
In the preceding example, we can see thatthis
"Usage, that is, we canthis
Assign a value to another variable. In ECMAScript 6, we can use the more elegant new technology, the arrow function to achieve similar results.
Arrow-functions does not passfunction
The keyword is created through the so-called "fat arrow" Operator (fat arrow,=>
. Unlike general functions, the arrow function obtainsthis
Value. The syntax binding of Arrow functions is not overwritten, even if the new operator is used.
Next let's take a look at how arrow functions are replaced.var self = this;
For this statement:
Var car = {brand: Nissan, getBrand: function () {// The Arrow function retains the syntax of this scope. var closure = () => {console. log (this. brand) ;}; return closure () ;}}; car. getBrand (); // output: Nissan
About
this
Knowledge Point
Like other mechanisms,this
Keywords also follow some simple rules. If you understand these rules, you can use them more smoothly. The following is a quick review of the knowledge points learned in these two sections:
In the following cases
this
It points to a global object:
In the code at the outermost layer, not in any function, it is not a constructor in the method function of the object method) when the function is called as the property of the parent object,
this
It points to the parent object ). When the function passes
call()
,
apply()
Or
bind()
When calling,
this
It points to the first parameter passed to these methods. If the first parameter is
null
Or is not an object
this
It points to a global object. In use
new
When an operator calls a function,
this
Point to the newly created object. When the arrow function is used in ECMAScript 6,
this
Points to the parent object (parent object) according to the syntax scope ).
After understanding these simple and direct rules, we can easily seethis
Which object is pointed to? If the point is incorrect, you can use the learned black technologies.
Summary
Masterthis
It is not easy, but if you use enough, you will naturally understand. I hope that this series of blog posts will help you lay a solid foundation and deepen your understanding. Then, you will be able to understand the relevant issues next time.