Js this points to the problem

Source: Internet
Author: User

Js this points to the problem

Js this points to the problem

Today, I will summarize the points of this in js. Today, I will understand the point of this through the way of the question, so I will not go into the theoretical depth. The theory will be further linked to the closure, scope chain, and so on.

Let's take a look at several topics:

1. When a function is directly called, The this pointer always points to the window
2. The anonymous function this always points to the window object.
3. Whoever executes the function, this points to WHO

4. If the function is new, an object is created and this points to the newly created object.

 

The following uses a lot of examples to compare this point

 

Var name = win; var obj = {name: obj, func: function () {var self = this; console. log (this. name); // objconsole. log (self. name); // obj // method a (function () {console. log (this. name); // winconsole. log (self. name); // obj} (); // Method B (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 question, a self variable is used to save the point of this, and the name outside obj is a global variable.

 

Method a and method B are actually the same, because they are all anonymous functions. According to Rule 2, this points to window, so this. name is equivalent to window. name, and the result is win.

In setTimeout, the first parameter is also an anonymous function, and this also points to the window, and the result is also win.

Self is the this point saved by obj, which always points to obj. Therefore, this. name is equivalent to obj. name, and the result is obj.

----------------------------------- 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
There should be no doubt about the 1st, this points to obj

 

The 2nd statement points this to a change, and this points to the window

3rd and 2nd are similar. Execute in the window environment in temp, so this points to the window

4th, 5, and 6 are all forced to bind the method getName to the window for execution, so this naturally points to the window


----------------------------------- Split line -----------------------------------

 

function test() {this.number = 10;alert(this.number);(function() {alert(this.number);}());};test();// 10 10
The test method is executed in the window environment. There is no doubt that the first this point points to the window. 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();// 10 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 this time, the first this points to the test object. Second, according to Rule 2, this points to window

 

Here is a similar small question. You can practice it:

 

var a = 5;function test(){    a = 0;    console.log(a);    console.log(this.a);    var a;    console.log(a);}test();// ?new test();// ?
Tip: we also need to understand how to improve the variable.

 

----------------------------------- Split line -----------------------------------

var length = 100;function fn(){    console.log(this.length)}function Test(a, b){var t1 = arguments.length;var t2 = Test.length;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 indicates the actual number of parameters, and Test. length indicates the number of defined parameters.

 

You can think about why the execution results of a () and arguments [0] () are different? A = arguments [0] returns true

It turns out that this is a strange thing. A () is executed in the window environment, so this points to the window. The arguments [0] () is executed in the arguments environment of the object. this points to arguments and calculates its length attribute. Naturally, it is 4, because its actual parameters are indeed four
----------------------------------- Split line -----------------------------------
Coming to a rather difficult question ^_^

 

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 // Step 2 fn1 (); // 9 // result: window. number = 8, number = 9, obj. number = 4 // step 3 obj. fn1 (); // 27 // result: window. number = 8, number = 27, obj. number = 8console. log (window. number); // 8console. log (obj. number); // 8

 

First, make it clear: obj. fn1 executes the first three rows during definition and returns a function, because it is a closure, obj. the content in fn1 is not destroyed after execution, but is stored in the memory.

Step 1: Assign the function returned after obj. fn1 is executed to the global variable fn1.

This. number * = 2. According to Rule 2, this points to window, which is equivalent to executing window. number * = 2, originally window. number is defined as 2, so window. number = 4.

Number = number * 2; var number = 3; variable escalation is involved here. The equivalent code is as follows:

 

var number;number = number * 2;number = 3;
The number of rows executed is undefined, the number of rows executed is NaN, and the number of rows executed is 3. Therefore, number = number * 2 is useless.

 

Okay. After completing the first step, sort out the values of each variable:

Window. number = 4, number = 3, obj. number = 4
Step 2: Execute the fn1 function, that is:

 

this.number *= 2;number *= 3;console.log(number);
Execute fn1 in the window, so this points to the window. After executing window. number = 4 in the previous step, after executing this. number * = 2, the window. number is changed to 8.

 

Number * = 3 was executed. We found that fn1 does not have the number definition. We need to look for the number in the upper-level scope. As we have already said, the closure has not been destroyed, it is still stored in the memory. After the first step is executed, the result is 3. Therefore, after the number * = 3 is executed, the value of number becomes 9.

 

After completing step 2, sort out the values of each variable:

Window. number = 8, number = 9, obj. number = 4

Step 3: Execute obj. fn1. According to rule 3, this points to obj, obj. number = 4

Run the following command under obj:

 

this.number *= 2;number *= 3;console.log(number);
Row 1st, this. number * = 2 is equivalent to obj. number * = 2. After execution, obj. number = 8;

 

Row 2nd, number * = 3: execution. The originally saved number = 9. After execution, number = 27

After completing step 3, sort out the values of each variable:
Window. number = 8, number = 27, obj. number = 8
----------------------------------- Split line -----------------------------------

Finally, we have another exercise question:

 

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);

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.