- This in Javascript is always confusing and should be one of the well-known pitfalls of Js. I personally think this in JS is not a good design. Due to the late binding feature of this, it can be a global object, the current object, or... Some people even use this because of a big pitfall.
- This in Javascript is always confusing and should be one of the well-known pitfalls of Js. I personally think this in JS is not a good design. Due to the late binding feature of this, it can be a global object, the current object, or... Some people even use this because of a big pitfall.
- In fact, if you fully grasp the working principle of this, you will naturally not go into these pitfalls. Let's take a look at what this points to in the following situations:
1. GlobalCodeIn this
Alert (This)//Window
This within the global range will point to the global object, even if the window is in the browser.
2. Simple function call
FunctionFoocoder (x ){This. X =X;} foocoder (2); Alert (X );//The global variable X value is 2.
Here this points to the global object, that is, window. In strict mode, it is undefined.
3. method call as an object
VaRName = "clever coder";VaRPerson ={Name:"Foocoder", Hello:Function(Something) {console. Log (This. Name + "says" +Something) ;}} person. Hello ("Hello World ");
Output foocoder says hello World. This indicates the person object, that is, the current object.
4. As a constructor
NewFoocoder ();
This inside the function points to the newly created object.
5. Internal functions
VaRName = "clever coder";VaRPerson ={Name:"Foocoder", Hello:Function(Something ){VaRSayhello =Function(Something) {console. Log (This. Name + "says" +Something) ;}; sayhello (something) ;}} person. Hello ("Hello World ");//Clever coder says hello World
In internal functions, this is not bound to the outer function object as expected, but to the global object. This is generally considered a javascript design error because no one wants to point this in internal functions to a global object. The general processing method is to save this as a variable, which is generally agreed to be that or self:
-
var name =" clever coder "; var person = {Name: " foocoder ", hello: function (something) { var that = This ; var sayhello = function (something) {console. log (that. name + "says" + something) ;}; sayhello (something) ;}} person. hello ( "Hello World"); /// foocoder says hello World
6. Use call and apply to set this
Person. Hello. Call (person, "world ")
The apply and call operations are similar, but the following parameters are passed in through an array instead of separately. Method definition:
Call (thisarg [, arg1, arg2 ,... ]);//Parameter List, arg1, arg2 ,...Apply (thisarg [, argarray]);//Parameter array, argarray
Both are used to bind a function to a specific object. Naturally, this is explicitly set as the first parameter.
Summary
Simply summing up the above points, we can find that only the sixth point is confusing.
In fact, we can summarize the following points:
1. When a function is called as an object's method, this points to this object.
2. When a function is called as a fade-out function, this points to a global object (undefined in strict mode)
3. This In the constructor points to the newly created object.
4. This in nested functions does not inherit this of upper-level functions. If necessary, you can use a variable to save this of upper-level functions.
To sum up the simplicity, if this is used in a function, this will point to this object only when the function is directly called by an object.
- OBJ. foocoder ();
- Foocoder. Call (OBJ ,...);
- Foocoder. Apply (OBJ ,...);
Further steps
We may often write such code:
- $ ("# Some-ele"). Click = obj. Handler;
If this is used in handler, will this be bound to OBJ? Obviously not. After a value is assigned, the function is executed in the callback. This will be bound to the $ ("# Some-Div") element. This requires understanding the execution environment of the function. This article does not describe the execution environment of functions in length. For more information, see JavaScript advancedProgramIntroduction to the execution environment and scope chain in design. This is a better understanding of the execution environment of JS functions.
So how can we solve the problem of callback function binding? Es5 introduces a new method, BIND ():
Fun. BIND (thisarg [, arg1 [, arg2 [,...]) thisarg when the binding function is called, this parameter will point to this when the original function is running. this parameter is invalid when the new operator is used to call the binding function. arg1, arg2 ,... when a binding function is called, these parameters plus the bound function parameters will be used as the original function runtime parameters in order.
- This method creates a new function called the binding function. The binding function uses the first parameter of the BIND method as this when it is created, the second and later parameters passed in the bind method plus the parameters bound to the function runtime are used as parameters of the original function in order to call the original function.
Obviously, the bind method can solve the above problems well.
$ ("# Some-ele"). Click (person. Hello. BIND (person ));//When the corresponding element is clicked, the output foocoder says hello World
In fact, this method is easy to simulate. Let's look at the source code of the BIND method in prototype. JS:
-
function. prototype. bind = function () { var fn = This , argS = array. prototype. slice. call (arguments), object = args. shift (); return function () { return fn. apply (object, argS. concat (array. prototype. slice. call (arguments) ;};