JS this pointing problem
Today, I would like to summarize the point of this problem in JS. Today through the topic of the way to understand this point, not from the theoretical depth, the theory in the future on the closure, the scope of the chain and so on when the link.
Let's start with a few programs:
1. When the function is called directly, the this pointer will always point to the window
2. Anonymous function This always points to the Window object
3. Who executes the function, this is pointing to WHO
4. If the function is new, an object is created and this points to the newly created object
The following is a comparison of a large number of examples to understand this point
var name = "Win"; var obj = {name: "obj", func:function () {var self = this;console.log (this.name);//Objconsole.log (self.na me);//obj //a method (function () {console.log (this.name);//Winconsole.log (self.name);//obj} ()); The B Method (function () {console.log (this.name);//Winconsole.log (self.name);/obj}) (); SetTimeout (function () { Console.log (this.name);//Winconsole.log (self.name);//obj}, 100);}} Obj.func ();
In this topic, a self variable is used to save the pointer to this, and the name outside of obj is a global variable.
The effect of A and B methods is actually the same, because they are anonymous functions, according to Rule 2, this time this point to the window, so this.name equivalent to window.name, the result is "win" naturally
The first parameter in SetTimeout is also an anonymous function, and it also points to window, and the result is also "win"
And self is the this point that obj has previously saved, it always points to obj, so this.name is equivalent to Obj.name, and the result is "obj" naturally.
-----------------------------------Split Line-----------------------------------
var name = "the window"; var obj = {Name: "My Object", Getname:function () {return this.name;}};/ /1console.log (Obj.getname ()); My Object//2console.log ((Obj.getname = Obj.getname) ()); The Window//3var temp = obj.getname;temp (); The Window//4console.log (Obj.getName.call (window)); The Window//5console.log (obj.getName.apply (window)); The Window//6console.log (obj.getName.bind (window)); The window
The 1th should have no doubt, this point to obj
The 2nd of this notation changes the this point, this point to the window
The 3rd is similar to the 2nd, which executes in the window environment in temp, so this points to the window
4th, 5, 6 are forced to bind the method getname to the window execution, so this is a natural point to the window
-----------------------------------Split Line-----------------------------------
function test () {This.number = 10;alert (this.number);(function () {alert (this.number);} ());}; Test ();//10 10
The test method executes in the window environment, where the first this point points to the window without any doubt. As for the second one, according to Rule 2, this points to window
function test () {This.number = 10;alert (this.number);(function () {alert (this.number);} ());}; New test ();//undefined
Here the function test is new, according to rule 4, if the function is new, an object is created, and this points to the newly created object, at which point the first one points to the test object. The second one points to the window according to the rule 2,this
Here's a small topic like this, which you can practice:
var a = 5;function Test () { a = 0; Console.log (a); Console.log (THIS.A); var A; Console.log (a);} Test ();//? New test ();//?
Tip: There's also an understanding of variable elevation
-----------------------------------Split Line-----------------------------------
var length = 100;function fn () { console.log (this.length)}function Test (A, b) {var T1 = Arguments.length;var T2 = TEST.L Ength;console.log (Arguments[0]); Console.log (a); Console.log (A = = Arguments[0]);//Truea ();//100arguments[0] ();// 4console.log (t1, T2);//4 2}test (FN, FN, FN, FN);
Arguments.length represents the actual number of arguments, test.length indicates the number of formal parameters defined
You can think about the results of a () and the results with Arguments[0] (). Clearly a = = Arguments[0] Returns True
Originally, is because this is in mischief. A () is executed in the window environment, so this is pointing to window. While Arguments[0] () execution is executed in the object arguments environment, this point to arguments, the length property, it is naturally 4, because its actual parameters are indeed 4
-----------------------------------Split Line-----------------------------------
To a comparison of the problem of the pit ^_^
var number = 2;var obj = {number:4,fn1: (function () {this.number *= 2;number = number * 2;var Number = 3;return function () {this.number *= 2;number *= 3;console.log (number);}}) (), Fn2:function () {This.number *= 2;}};/ /The first step var fn1 = obj.fn1;//Result: Window.number = = 4, Number = = 3, Obj.number = = 4console.log (number);//4//Second step fn1 ();//9//Result: w Indow.number = = 8, Number = = 9, Obj.number = = 4//Third step obj.fn1 ();//27//Result: Window.number = = 8, Number = =, Obj.number = 8 Console.log (Window.number);//8console.log (Obj.number);//8
The first thing to be clear: Obj.fn1 executes the previous 3 lines at the time of definition, and returns a function that, because it is a closure, is not destroyed when the content in the OBJ.FN1 is executed, but remains in memory.
The first step is to assign the function returned after OBJ.FN1 execution to the global variable FN1.
When the function executes, This.number *= 2, according to the rule 2,this point to window, equivalent to execute Window.number *= 2, originally window.number is defined as 2, so window.number = = 4 at this time.
Number = number * 2; var number = 3; Here is the variable promotion, the equivalent code is as follows:
var number;number = number * 2;number = 3;
The 1th line executes the number is undefined, the 2nd line executes the number is Nan, and the 3rd line executes the number 3; so here's number = number * 2;
Well, the first step is done, and the values of each variable are sorted out at this point:
Window.number = = 4, Number = = 3, Obj.number = = 4
The second step is to execute the function fn1, which is:
This.number *= 2;number *= 3;console.log (number);
At this point the FN1 is executed under window, so this points to window, the previous step executes window.number = = 4, after execution This.number *= 2 Window.number becomes 8
The turn to execute number *= 3, we found that there is no number in FN1 definition, need to go to the scope of the previous level to find number, previously said, the closure is not destroyed, is still stored in memory, the first step is completed after the result is 3, so the execution of the number *= The value of number after 3 becomes 9
After the second step, we'll tidy up the values of each variable:
Window.number = = 8, Number = = 9, Obj.number = = 4
The third step, execute obj.fn1, according to Rule 3, this time this point obj,obj.number = = 4
Obj execution:
This.number *= 2;number *= 3;console.log (number);
1th line, This.number *= 2 equivalent to Obj.number *= 2, after execution, obj.number = = 8;
Line 2nd, number *= 3 execution, the original saved number = = 9, after execution, number = = 27
After the third step, we'll tidy up the values of each variable at this point:
Window.number = = 8, Number = =, Obj.number = 8
-----------------------------------Split Line-----------------------------------
Finally, there is an exercise topic:
function test () {this.data = 5;this.log = function () {console.log (this.data);}} var a = new test (); A.log ();//? (A.log) ();// ? (A.log = a.log) ();// ? var B = a.log;b ();//? (function () {a.log ();//? }); SetTimeout (A.log, 100);//? SetTimeout (function () {a.log ();//? }, 100);
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
JS this pointing problem