In-depth understanding of this point in JS from the ECMA specification

Source: Internet
Author: User
Tags argumentlist

This is a concept in object-oriented programming, which generally points to the object where the current method call resides, which is very clear in the more restrictive object-oriented programming languages such as Java and C + +. But in JavaScript, the definition of this is much more flexible, and if not mastered accurately, it is very easy to confuse. I also found in the interview process, the interviewer rarely have to be able to answer very comprehensive. This article summarizes the various cases of this and explores the specific implementation of this from the perspective of the ECMA specification, hoping to help you understand this.

This refers to the four-medium situation

In JavaScript, this point can be summarized in the following four cases. As long as you can keep these four things in mind, most of the cases are sufficient.

1. In a global code or a normal function call, this refers to the global object, which is both a Window object in the browser.

    console.log(this);//输出window        function foo(){ console.log(this); } foo();//输出window

Running the above code in a browser environment, both outputs are window objects.

2. Call the function by calling or the Apply method, which points to the first parameter of the method invocation.

    var obj = {name:‘test‘};        function foo(){ console.log(this); } foo.call(obj);//输出obj foo.apply(obj);//输出obj

Execute the above code in a browser environment and the output will be object obj. Call and apply in addition to the same parameters, call is separated by commas, apply the array. Speaking of which, incidentally, a little trick. How do I implement a connection between two arrays without generating a new array? Take a look at the following code.

    var arr1 = [1, 2 , 3],        arr2 = [4, 5, 6]; Array.prototype.push.apply(arr1, arr2); console.log(arr1);//输出[1, 2, 3, 4, 5, 6]

After executing the above code, the output is [1, 2, 3, 4, 5, 6]. This is a very practical trick, because the second parameter of apply is in the form of an array, so we can "borrow" the push method to achieve the connection between the two arrays.

3. Invoke the object's method, which points to the object.

    var obj = {name:‘test‘};        function foo(){ console.log(this); } obj.foo = foo; obj.foo();//输出obj

After executing the above code, the console output is an obj object. This is what we often say about "who calls, who points to".

4. Constructs this in the method, pointing to the newly constructed object.

    function C(){        this.name = ‘test‘; this.age = 18; console.log(this); } var c = new C();//输出 c console.log(c);//输出 c

After executing the above code, the console output is the object that C points to. When the new operator is used for a function, it is created and pointed to by this object.

ECMA specification

The implementation details of this are described in detail in the ECMA specification, and by reading the specification, we can more accurately understand what is going on in these four cases.
A function object has an internal method called [[Call]], and the execution of the function is actually performed through the [[Call]] method. The [[Call]] method receives two arguments Thisarg and Argumentlist,thisarg and this point have a direct relationship, ArgumentList is the argument list of the function. And how did Thisarg come? We can correspond to the four scenarios discussed earlier:

    1. The normal method call Thisarg is undefined.

    2. Called by call or Apply, Thisarg is both the first parameter.

    3. Called by the object, Thisarg points to the object.

    4. In the construction method, Thisarg is the newly constructed object.

What is the relationship between Thisarg and this? The description in the specification is this:

    1. If The function code is strict code, set the thisbinding to Thisarg.

    2. Else if Thisarg is a null or undefined, set the thisbinding to the global object.

    3. Else if Type (Thisarg) is not an Object, set the thisbinding to Toobject (Thisarg).

    4. Else set the thisbinding to Thisarg.

In strict mode, the Thisarg and this are one by one corresponding.

function foo(){ ‘use strict‘; console.log(this);}foo();//输出undefined

The result of the example output is undefined.

The 2nd is that if thisarg is null or undefined, this points to the global object.

function foo(){    console.log(this);}foo.call(null);//输出window

The output of the example is window.

The 3rd says that if Thisarg is non-object type, it will be coerced into an object type.

function foo(){    console.log(this);}var aa = 2;console.log(aa);//输出2foo.call(aa);//输出 Number

The output here is 2 and number, respectively, which transforms the base type into the object wrapper type.

The 4th describes the remainder of the Thisarg and this corresponds to the one by one relationship.

The description of this point in the specification is still relatively clear. As long as you figure out how Thisarg is sure, the correspondence between Thisarg and this, then you can take care of all this.

Make sure the point of this

In the actual use of this, the most encountered problem is probably the problem of context loss. Because a function in JavaScript can be passed as a parameter, other objects can cause the callback function to lose its original context when executing the callback function, which means that this point is changed.

var C = function(){    this.name = ‘test‘; this.greet = function(){ console.log(‘Hello,I am ‘+this.name+‘!‘); };}var obj = new C();obj.greet();//输出 Hello,I am test!setTimeout(obj.greet, 1000);//输出 Hello,I am !

It is visible that the value of this in the second output has changed, in fact we want this to point to obj. There are two ways to solve this problem.

1.bind method. The
Bind method cleverly implements the binding of the context through closures, which in effect wraps the original method into a new method. The general implementation is as follows:

Function.prototype.bind = function(){    var args = arguments, thisArg = arguments[0], func = this; return function(){ var arg = Array.prototype.slice.call(args, 1); Array.prototype.push.apply(args, arguments); return func.apply(thisArg, arg); }}

The previous example code we just need to add bind, we can get the results we want.

1000);//输出 Hello,I am test!...

2.es6 arrow function.
ES6 inside provides a new syntax for sugar, arrow functions. The This of the arrow function is no longer unpredictable, it always points to the this value when the function is defined.

var C = function(){    this.name = ‘test‘; this.greet = ()=>{ console.log(‘Hello,I am ‘+this.name+‘!‘); };}var obj = new C();obj.greet();//输出 Hello,I am test!setTimeout(obj.greet, 1000);//输出 Hello,I am test!

The previous example should be the arrow function, and the output will be the same in both places. The value of this does not change anymore, which is what we want.

Summary

This seems to be a very small knowledge point, actually digging up still have a lot of details, especially the specification inside some definitions, I think for a JS programmer is very important. I am also ready to find some of the ECMA norms inside the knowledge points and share, I hope to be helpful to everyone. As I have limited ability, I would like to point out where I understand the error.

Original: 1190000003906484

In-depth understanding of this point in JS from the ECMA specification

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.