Stop worrying about this.------the this mechanism in JS

Source: Internet
Author: User

Preface: There are a lot of confusing places in JavaScript, or mechanisms. But these are the things that make JavaScript look so good and different. For example, functions are objects, closures, prototype chain inheritance, and so on, which includes a rather confusing this mechanism. Whether it is a novice or veteran, do not carefully dig a bit and really do not understand this fell on the ground to pinch. Today, we'll take a look at this, and don't worry about this.

1. What is this?

In short, this is one of the many keywords defined in the JavaScript language, which is special in that it is automatically defined in every function domain, but this falls on the ground and leads to a lot of people who don't mind. Here we leave a little suspense, hope to read this article, you can answer this is the guide a very much.

2. What is the use of this?

The audience should ask again, since this is so difficult to understand, then for a very much to use it? Let's look at an example:

1 function Identify () {2     return this.name.toUpperCase (); 3} 4 function SayHello () {5     var greeting = "Hello, I ' m "+ Identify.call (this); 6     Console.log (greeting); 7} 8 var person1= {9     name: "Kyle",};11 var person2= {Ten     name: "Reader"};14 I Dentify.call (Person1); KYLE15 Identify.call (Person2); READER16 Sayhello.call (Person1); Hello, I ' m KYLE17 sayhello.call (Person2); Hello, I ' m READER

This code is simple, we have defined two functions, identify and SayHello, respectively. And they are implemented in different object environments to achieve the effect of multiplexing, instead of having to write corresponding functions for different object environments in order to perform in different object environments. In short, this gives the function a reuse. There Sir asked again, I do not use this as can be achieved, such as:

1 function Identify (context) {2     return context.name.toUpperCase (); 3} 4 function SayHello (context) {5     var greet ing = "Hello, I ' m" + identify (context); 6     Console.log (greeting); 7} 8 var person1= {9     name: "Kyle",};11 var person2= {Ten     name: "Reader"};14 I Dentify (Person1); KYLE15 identify (Person2); READER16 SayHello (Person1); Hello, I ' m KYLE17 SayHello (Person2); Hello, I ' m READER

In a closer look, the solution given by the Sir has indeed achieved similar results. Praise One! What I want to say is that as the code grows, the nesting of functions, the invocation of all levels, and so on are becoming more and more complex, so it becomes increasingly unwise to pass in a reference to an object, which makes your code very messy, even if you can't understand it yourself. The This mechanism provides a more elegant and flexible solution, passing an implicit object reference to make the code more concise and reusable. Well, knowing the usefulness of this, then look at our misunderstanding of it.

3. Misunderstanding about this

Many children's shoes are believed to have learned other languages, and in many programming languages there is a mechanism for this, and inertial thinking brings the understanding of other languages to JavaScript. At the same time, the understanding of this word causes us to have a variety of misunderstandings about it. So, before we start, let's clarify the misunderstanding.

3.1 Misunderstanding one: This refers to the function itself

As we all know, referencing functions in a function can achieve recursion and the effect of assigning values to function properties. This is useful in a number of scenarios. So, many people mistakenly think this is the guiding function itself. For example:

1 function fn (num) {2     Console.log ("fn:" + num); 3     //count is used to record the number of calls FN 4     this.count++; 5} 6 fn.count = 0; 7 var i; 8 for (i=0; i<10; i++) {9     if (i > 5 ) {Ten         fn (i);     }12}13//fn:614//fn:715//fn:816//fn:917 Console.log (Fn.count);//0--yes? Why not 4 pinch?  

Above we want to record the number of times FN was called, but the apparent FN was called four times but count is still 0. What's the pinch? Here is a simple explanation, the 4th line of FN in the self-increment implicitly creates a global variable count, because the initial value is undefined, so each time the increment is still not a number, you in the Global Environment Print count (window.count) output should be Nan. The 6th line defines the function familiarity variable count remains unchanged, or 0. If the results of this implementation is not clear, welcome to see my previous days of the blog post (talk about the scope of JS and closure closure scope and closure), here you just need to know, this refers to the function of this understanding is wrong on the line.

This side will be asked again, since this is not a reference function, then I want to implement a recursive function, how to reference it? Here's a quick answer to a question, Two methods: The ① function body uses the function name to refer to the function itself ② function body using Arguments.callee to refer to the function (not recommended). So since the second method is not recommended, how can anonymous functions be quoted? Use the first, and give the anonymous function a functional name (recommended).
3.2 Misunderstanding two: This refers to the lexical scope of the function

This misunderstanding may deceive more people. First, clarify that this does not refer to the lexical scope of function. Indeed, the implementation of the lexical domain in the engine of JS is really like an object, owning properties and functions, but this is just an implementation of the JS engine, which is invisible to the code, that is, the lexical scope "object" is not available in the JS code. (For lexical scopes, if you don't understand, you can refer to a previous post, "Talk about the scope scope and closure closure scope and closure in JS"). Take a look at the wrong example:

1 function fn1 () {2     var a = 2;3     this.fn2 ();//For this reference is FN1 lexical scope 4}5 function fn2 () {6     console.log (THIS.A); 7 }8 fn1 (); Referenceerror

The above code obviously does not perform the desired result, so you can see that this does not refer to the lexical scope of the function. Even, to be sure, in this case fn2 can be executed correctly in fn1 (understanding the lexical scope you know why there is no error in the execution).

4. What does this have to do with what?

Okay, so much has not dried up, and some viewers are starting to close the current page and start to leave. Here, we solemnly declare: this and function where the definition is not a half-gross money relationship, where the function is called to determine what this exactly refers to. That is, this is not the same as the definition of the function, and the function of the implementation of a large relationship. So, remember, "where the function is called determines what this is referring to".

5. The four rules of this mechanism

This is exactly where the object environment is bound or referenced by the function being called. The invocation of a function has a different way of calling, in a different way, to determine which object this reference is determined by four rules. Let's take a look.

5.1 Default binding global variables

This rule is the most common and is the default. When a function is defined and called separately, the rule applied is to bind the global variable. As follows:

1 function fn () {2     console.log (THIS.A), 3}4 var a = 2;5 fn ();//2--FN is called separately, this refers to window

5.2 Implicit binding

Implicit invocation means that a function call has a context object, as if the function belonged to that object. For example:

1 function fn () {2     console.log (THIS.A), 3}4 var obj = {5     a:2,6     fn:fn7};8 Obj.fn ();//2--this references obj.

One point to note is that the last object to invoke the function is the context object that is passed to the function (which is a bit of a rip). Such as:

1 function fn () {2     console.log (THIS.A); 3} 4 var obj2 = {5     a:42, 6     fn:fn 7}; 8 var obj1 = {9     a:2 , ten     obj2:obj211};12 Obj1.obj2.fn (); -this refers to OBJ2.

It is also important to note that the case of the loss of implicit binding is as follows:

1 function fn () {2     console.log (THIS.A); 3} 4 var obj = {5     a:2, 6     fn:fn 7}; 8 var bar = Obj.fn;//function lead By passing 9 var a = "global"; Define global variables of ten bar (); Global

As above, line 8th has implicit binding, but the effect is obviously to assign FN to bar. When the bar executes, it remains the default binding global variable, so the output is as above.

5.3 Show Bindings

Learn that the bind () \apply () \call () function should know that the first parameter it receives is the context object and assigns it to this. Look at the following example:

1 function fn () {2     console.log (THIS.A); 3}4 var obj = {5     a:26};7 fn.call (obj);//2

If we pass the first value to a simple value, then the background is automatically converted to the corresponding encapsulated object. If passed to null, the result is binding the default global variables, such as:

1 function fn () {2      console.log (THIS.A); 3  }4  var obj = {5      a:26  };7 var a = 10;8 Fn.call (null);//1 0

5.4 New Object Binding

If it is a constructor, then it is called with new, then the newly created object is bound. Such as:

1 function fn (a) {2     this.a = a;3}4 var bar = new FN (2); 5 Console.log (BAR.A);//2

Note that the general constructor name is capitalized, and there is no capitalization to remind the reader that the constructor is also a general function.

6. Concluding remarks

Read now, 1 questions you should be able to answer. The four kinds of conditions and rules described above for this binding are certainly more and more complex in the process of writing code, but no matter how complex and chaotic they are, they are just a few of the rules and circumstances of a hybrid application. As long as your ideas and understanding are clear, it is certainly not a problem.

Stop worrying about the this mechanism in------JS

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.