The This keyword in javascript

Source: Internet
Author: User

The This keyword in javascript

The keyword this in a JavaScript function does not refer to itself (itself), for example:

 function foo(num) {Console.log ("foo:"+ num);//Keep track of what many times ' foo ' is called     This. count++;} Foo.count =0;varI for(i=0; i<Ten; i++) {if(I >5) {foo (i); }}//Foo:6//Foo:7//Foo:8//Foo:9//How many times is ' foo ' called?Console.log (Foo.count);//0

Although Foo () was executed 4 times in the example above, the Foo.count is still 0, indicating that this is not the Foo function itself. So what is the value of the count++ that we are doing is increasing? In fact, we created a global variable count, which is a variable under window, and its initial value is Nan, even if it is incremented 4 times, its value is still nan.

It is easy to understand if the above example is changed below:

function foo (num) {Console.Log("foo:" +NUM);//Keep track of what many times ' foo ' is called    Data.Count++;}var Data ={count:0};varI;for (i=0; I<Ten; I++) {if(I> 5) {foo (i); }}//Foo:6//Foo:7//Foo:8//Foo:9//How many times is ' foo ' called?Console.Log(Data.count);//4

But here, we didn't use the This keyword, we just selectively dodged this, using another way to-lexical scope.

If we want to refer to itself within a function, we can only use lexical identifier (variable) to point to itself, as follows:

function foo() {    4// `foo` refers to itself}

This is useful for functions with function names, but not for anonymous functions, such as the following:

function(){    function (no name), cannot    10 );

There is nothing we can do about it, but there is one that does not recommend using the function itself in a way that is currently deprecated: Arguments.callee, in fact, the best way to do this is to avoid using anonymous functions when referencing the function itself, thus avoiding the occurrence of these problems.

So at the very beginning, if we were to refer to our own function, we would use its own function name (identifier):

function  foo   (num)  { Console.log (  "foo:"  + num); //keep track of what many times ' foo ' is called  foo.count++;} Foo.count = 0 ; var  i; for  (I=0 ; I<10 ; i++) {if  (i > 5 ) {foo (i); }}//foo:6  //foo:7  //foo:8  //foo:9  //how many times is ' foo ' called?  Console.log (Foo.count); //4  

In the example above, we still seem to be avoiding the This keyword, except in the example above we have to refer to the function itself, we cannot use the This keyword.

If we must use the This keyword to refer to the function itself, we can do this:

functionFoo (num) {Console. log ("foo:"+ num);//Keep track ofHow many times 'Foo` isCalled// Note: ` This' is actually 'Foo' Now, based on    //How 'Foo` isCalled (see below) This. count++;} Foo.count =0;varI for(i=0; i<Ten; i++) {if(I >5) {//Using 'Call (..)', we ensure the ' This`//Points at thefunctionObject ('Foo') itself Foo.call (foo, i); }}// Foo:6//Foo:7//Foo:8//Foo:9How many times is 'Foo' Called?Console. log (Foo.count);// 4

Another misconception about this is that this refers to the function of the lexical scope,you Dont Know JS in relation to this:

To is clear, this does not, on any, and refer to a function ' s lexical scope. It is true that internally, scope is kind of the "like" object with properties for each of the available identifiers. But the scope "object" was not accessible to JavaScript code. It's an inner part of the Engine ' s implementation.

Take a look at the following example:

function foo() {    var2;    this.bar();}function bar() {    this//undefined

The code above attempts to build a bridge through the lexical scopes of Foo () and bar (), so the inner scope variable a of Foo () is obtained through bar (), and such a bridge does not actually exist.

So what exactly is the this mechanism? In fact, this is bound at runtime (runtime binding), not when it is created (author-time binding), that is, the function is bound based on its context when invoked.

You Dont Know JS in about the this mechanism has such a passage:

' This ' isn't a author-time binding but a runtime binding. It is contextual based on the conditions of the function ' s invocation. The This binding have nothing to does with where a function are declared, but have instead everything to does with the manner in whic H the function is called.

When a function was invoked, an activation record, otherwise known as an execution context, was created. This record contains information about where the function is called from (the Call-stack), how the function is invoked, What parameters were passed, etc. One of the properties of this record are the this reference which would be used for the duration of that function ' s executio N.

As mentioned above, this is bound based on its call-site when the function is called, so what is Call-site?

Call-site:the location in code where a function is called (not where it ' s declared).

So how do you determine the call-site of a function?

Go locate where a function is called from

However, determining the call-site of a function is not easy, so let's take a different approach to finding the call-stack of the function:

The stack of functions that has been called to get us to the current moment in execution

Let's take an example to illustrate the relationship between Call-site and Call-stack:

functionBaz () {//Call-stack is: `Baz`//So, our Call-site is inchTheGlobalScopeConsole. log ("Baz"); Bar ();//<--Call-site for`Bar`}functionBar () {//Call-stack is: `Baz` -`Bar`//So, our Call-site is inch`Baz`Console. log ("Bar"); Foo ();//<--Call-site for`Foo`}functionFoo () {//Call-stack is: `Baz` -`Bar` -`Foo`//So, our Call-site is inch`Bar`Console. log ("foo");} Baz ();//<--Call-site for`Baz`

We can debug the call-stack of the view function through the debugger of the browser's dev tool.

After we clear the call-site, let's look at the four guidelines for this binding:

1. Default Binding

This is the most common binding rule, which means that this is pointing to global object, see example:

function foo() {    this.a );}var2// 2

If under strict mode, this points to undefined:

function foo() {    "use strict";    this.a );}var2// TypeError: `this` is `undefined`

One of the details to note is that if Foo () is not under strict mode, its this still points to the global object:

function foo() {    this.a );}var2;(function(){    "use strict";    // 2})();
2. Implicit Binding

Does the call-site has a context object, also referred to as an owning or containing object

If the Call-site has a context object, or if it has a container object that contains it, then the implicit binding works at this point, see the following example:

function foo() {    this.a );}var obj = {    2,    // 2

In the example above, Foo is first declared and then referenced by obj, and in fact, even if the function is declared in obj, the result is the same:

var obj = {    a: 2,    foo: function() {           console.log( this.a );          }};obj.foo(); // 2

Call-site uses the obj context to reference the function, so you could say that the Obj object "owns" or "contains" the FU Nction Reference at the time of the function is called.

Obj holds a reference to the Foo function before the Foo () function is called, that is, obj is the context object of Foo, at which point the implicit binding takes effect and this also points to the context object. Note the following scenario:

function foo() {    this.a );}var obj2 = {    42,    foo: foo};var obj1 = {    2,    // 42

Consider the following example:

function  foo () { Span class= "hljs-built_in" >console . Log (this . a);} var  obj = {a : 2
     , foo : foo}; var  bar = Obj.foo; // function  reference/alias! var  a =  "oops, global" ; // ' a  ' also property  On  global  Objectbar (); //  "oops, global"   

On the surface, bar is pointed to the Foo function through the foo attribute of obj, in fact, bar is a reference directly to Foo, because Foo in obj is also referred to by Foo. At this point, because this loses the binding, the default binding takes effect.

function  foo   ()  { console.log (this . a);} function  doFoo  Span class= "Hljs-params" > (FN)  { //' FN ' is just another reference to ' foo '  fn (); //<--call-site! } var  obj = {A: 2 , Foo:foo};var  a = " oops, global "; //' A ' also property on global object  Dofoo (Obj.foo); //"oops, global"   

Here, we assign the Foo function reference to fn by parameter passing, it's not about obj, it's FN pointing to the Foo function reference, this loses the implicit binding, and the default binding takes effect, even if the function you passed in the callback function (that is, FN here) is not written by yourself:

function foo() {    consolethis.a );}var obj = {    a2,    foo: foo};var"oops, global"// `aonglobal100//"oops, global"

Here's the settimeout we can understand:

function setTimeout(fn,delay) {    // wait (for `delay` milliseconds    fn(// <-- call-site!}

This is consistent with the above.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

The This keyword in javascript

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.