This keyword in javascript

Source: Internet
Author: User
This article introduces the this keyword in javascript and lists the knowledge about this keyword into a list, which will help us to clarify our ideas and be a good learning method. It is strongly recommended. No matter what knowledge we learn, we are used to listing the learned knowledge into a list, which will help us to clarify our ideas and be a good way to learn. It is strongly recommended.

The following sections are a bit long and I hope readers can read them patiently.

The following content is divided into the following parts:

1. Meaning

1.1: meaning of this

1.2: variability of this point

2. Application scenarios

2.1: Global Environment

2.2: Constructor

2.3: Object Method

3. Usage notes

3.1: Avoid Multi-layer nesting this

3.2: Avoid this in the Array Processing Method

3.3: Avoid this in the callback function

1. Meaning

1.1: meaning of this

In my post on the relationship between constructors and new keywords, The new Keyword always returns an object. This object can be an empty object returned when the new constructor is called, or a complex data type (including objects and arrays) returned by the return Statement in the constructor ).

Similarly, like the new Keyword, this keyword always returns an object. In detail, it is the object where the attribute or method "current" is located.

var Keith = {  firstName: 'Chou',  describe: function() {   return this.firstName;  } };console.log(Keith.describe()); //'Chou'

In the code above, this. firstName indicates the firstName attribute of the current object of the describe method. That is to say, when the describe method is called globally, the current object of the describe method is Keith, so it is to call Keith. firstName.

1.2: variability of this point

Because the attributes of an object can be assigned to another object, the current object of the attribute is variable. That is to say, the point of this is variable.

var Keith = {  firstName: 'Chou',  describe: function() {   return this.firstName;  } }; var Rascal={  firstName: 'King' } Rascal.describe=Keith.describe; console.log(Rascal.describe()); //'King'

In the code above, the describe attribute in the Keith object is assigned to Rascal, so the current object in the describe method is Rascal, so this. firstName points to Rascal. Because it is an address transfer, modifying the firstName will affect the original object. This example may not be easy to understand. Let's look at the example below.

function f(){  return this.firstName; } var Keith = {  firstName: 'Chou',  describe:f }; var Rascal={  firstName: 'King',  describe:f } console.log(Keith.describe()); //'Chou' console.log(Rascal.describe()); //'King'

In the code above, the method is moved to the global scope, and function f uses the this keyword internally. With the object where f is located, this points to a different one.

In the global scope, this keyword will point to the top-level object (that is, the window object ).

var name='keith'; function person(){  var name='rascal';  return this.name; }console.log(person()); //'keith'

In the above Code, keith is returned instead of rascal. The reason is that this points to the global scope. Define a function in the global scope. By default, the function points to the window object rather than the function itself. However, if the function does not use var to declare a local variable, the result will be different.

var name='keith'; function person(){  name='rascal';  return this.name; }console.log(person()); //'rascal'

In the code above, the function does not use var to declare a local variable, so the name attribute inside the function is not a local variable, but a global variable. Therefore, the previous name attribute is overwritten. If you are not familiar with local variables and global variables, visit this article.

As long as the function is assigned to another variable, the point of this changes.

var Keith={  name:'keith',  describe:function(){   return this.name;  } }var name='rascal';var f=Keith.describe;console.log(f()) //'rascal'

In the above Code, rascal instead of keith is returned. Because Keith. describe is assigned to the f variable, and there is a name variable in the global scope. Therefore, this point of the function in Keith will point to the object (top-level object, that is, the window object)

Summary:

1. In javascript, everything is an object (except for undefined and null), and the runtime environment is also an object. Therefore, all functions are run in an object. this is the object (Environment ).

2. The point of this is dynamic. If the function is in the global scope, this points to the global environment. If the function is located in an object, this points to this object.

2. Application scenarios

This can be used in the following scenarios.

2.1: Global Environment (global scope)

Use this object in the global scope. It points to the top-level object, that is, the window object.

function keith() {  return (this === window)  }console.log(keith()) //true

In the code above, whether it is inside the function or not, as long as it runs in a global scope, this is to point to the top-level Object window.

2.2: Constructor

This in the constructor points to the object instance to be created.

function Keith() {  this.sex = 'boy'; } var person = new Keith(); console.log(person.sex); //'boy'

In the code above, the Keith constructor is defined in the global scope, and then the constructor is called and assigned to the person object instance.

Three basic requirements for Constructor creation: the first letter of the function name is capitalized; the constructor uses the this keyword to point to the object instance to be generated; the new keyword is used to call the constructor and return the object instance.

To learn more about the relationship between constructor and the new Keyword, go to this article.

2.3: Object Method

When the method of object A is assigned to object B, this in the method changes from pointing to object A to pointing to object B. So be careful when assigning the method of an object to another object, the point of this will be changed.

var keith = {  sex: 'boy',  foo: function() {   return this.sex;  } }; var rascal = {  sex: 'girl' }; rascal.foo = keith.foo; console.log(keith.foo()); //'boy' console.log(rascal.foo()); //'girl'

In the above Code, the foo function of keith is assigned to rascal, so the point of this is changed from keith to rascal.

If a method is located inside a multi-layer object, the method is assigned to a variable to simplify writing, and different results are often obtained.

var a = {  b: {   p: 'keith',   c: function() {    return this.p;   }  } }; var person = a.b.c; console.log(person()); //undefined

In the code above, c is a method in two layers of objects. For ease, assign the value to the global variable person. When the result is called, this points to the top-level Object window. The default value of Variable p in window is undefined.

To solve this problem, you can assign only the object of c to the person variable, or call it directly.

var person = a.b;console.log(person.c()); //'keith'console.log(a.b.c()); //'keith'

3. Usage notes

3.1: Avoid Multi-layer nesting this

When multiple layers of this are used in the closure, this points to the window.

function keith() {  console.log(this);  return function() {   return this;  } } keith(); //window keith()(); //window

In the code above, returning another anonymous function in a function is one of the characteristics of the closure. It can be seen that when this object is used in the closure, it will point to the window object in the global scope.

If a function contains an object, this points to the global scope, and the external this object points to the current scope.

var o = {  f1: function() {   console.log(this);   (function() {    console.log(this)   })();  } }; o.f1(); //Object , Window

The above Code contains two layers of this. After the result is run, the first layer points to the current object, and the second layer points to the global object.

The following code is actually executed.

function keith() {  console.log(this); } var o = {  f1: function() {   console.log(this);   var f2 = keith();  } }; o.f1(); //Object , Window

There are two solutions to implement multi-layer this nesting:

First, use a variable pointing to the outer layer this in the second layer.

var o = {  f1: function() {   console.log(this);   var that = this;   (function() {    console.log(that);   })();  } }; o.f1(); //Object , Object

In the code above, the local variable that is defined, fixed to the outer this, and then used that in the internal layer, there will be no change in the direction of this. However, if a nested object exists outside the function, this still points to the global.

Second, the strict mode in Javascript. In strict mode, if this of the internal function points to the window object, an error is returned.

var a = {  count: 0,  fun: function() {   'use strict';   return this.count++;  } } var f = a.fun; console.log(f()) //'TypeError: this is undefined'

In the above Code, the fun method uses the strict mode declaration. Assign the fun method in object a to the global variable f, so this points to the window object. In strict mode, an error is returned. If no object is nested outside the function, no error is reported, but undefined is returned.

3.2: Avoid this in the Array Processing Method

The map and foreach methods of arrays allow a function to be provided as a parameter. This function should not be used internally.

var keith = {  a: 'Hello',  b: ['b1', 'b2'],  c: function() {   this.b.forEach(function(item) {    console.log(this.a + ' ' + item);   })  } }; keith.c(); //undefined b1 //undefined b2

In the code above, this in the callback function of the forEach method actually points to the window object, so it cannot get the value of keith. a. The same as above also avoids multi-layer nesting of this. That is to say, this in the inner layer does not point to external functions, but to top-level objects.

To solve this problem, you can use that variable to replace this in the callback function.

var keith = {  a: 'Hello',  b: ['b1', 'b2'],  c: function() {   var that = this;   this.b.forEach(function(item) {    console.log(that.a + ' ' + item);   })  } }; keith.c(); //Hello b1 //Hello b2

Another method is to use this as the second parameter of the forEach method to fix its runtime environment.

var keith = {  a: 'Hello',  b: ['b1', 'b2'],  c: function() {   this.b.forEach(function(item) {    console.log(this.a + ' ' + item);   }, this)  } }; keith.c(); //Hello b1 //Hello b2

3.3: Avoid this in the callback function

This in the callback function often changes the point.

var o = {  f: function() {   console.log(this === o);  } }; o.f(); // true;

In the code above, call the f method of the o object and return true.

However, if the f method is specified to a button's click Event, the point of this changes.

$ ('Click'). on ('click', o. f );

In the code above, the jquery method is used to obtain the button element and bind the click event. After you click the button, the console displays false. The reason is that this no longer points to the o object, but to the DOM object of the button, because the f method is called in the environment of the button object.

Summary:

A: If you want to nest the this keyword in multiple layers, the most common solution is to use the that variable to fix this pointing to the outer layer, and then use that variable in the internal layer. This will not cause the problem that the inner layer points to the global layer.

B: If you use the this keyword in the callback function, pay attention to the point of this.

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.