How to use this in JavaScript

Source: Internet
Author: User
Tags sessionstorage
Tip: First of all, I know this article is boring. It is nothing more than this in js, and thousands of articles have already written this part. However, I still want to write an article about this in js, which is a summary. (You can refer to my other articles.) In js, the context of this is always unpredictable, in many cases, bugs are always confused. In fact, you only need to clarify the tip.

First of all, I know this article is boring. It is nothing more than this in js, and thousands of articles have already written this Part;

However, I still want to write an article about this in js, which is a summary. (You can refer to my other articles)

In js, the context of this is always unpredictable. In many cases, bugs are always confused. In fact, it is okay to know how to execute it in different situations.

Global execution

First, let's look at what this is in the global environment:

First. Browser:

Console. log (this );

// Window {speechSynthesis: SpeechSynthesis, caches: CacheStorage, localStorage: Storage, sessionStorage: Storage, webkitStorageInfo: DeprecatedStorageInfo ...}
The output is

window

Object;

Second. node:

Console. log (this );

// Global
The output is

global

Object;

Summary: In the global scope, its

this

Execute the current global object (the browser side is

Window

In node

global

).

Execute pure function calls in Functions

This is the most common function usage method:

Function test (){
Console. log (this );
};

Test ();

// Window {speechSynthesis: SpeechSynthesis, caches: CacheStorage, localStorage: Storage, sessionStorage: Storage, webkitStorageInfo: DeprecatedStorageInfo ...}
We can see that when a function is called directly, it is a global call.

this

Point to a global object;

Strict mode 'use strict ';

If you execute pure function calls in strict mode

this

It does not point to the global,

undefined

To eliminate some of the less rigorous JavaScript behaviors:

'Use strict ';
Function test (){
Console. log (this );
};

Test ();

// Undefined
Of course, it would be better to put it in an immediate execution function to avoid global contamination:

(Function (){
"Use strict ";
Console. log (this );
})();

// Undefined

Method call as an object

When a function is called as a method of an object:

Var obj = {
Name: 'qiut ',
Foo: function (){
Console. log (this. name );
}
}

Obj. foo ();

// 'Qiutc'
At this time,

this

Point to the current object;

Of course, we can also do this:

Function test (){
Console. log (this. name );
}
Var obj = {
Name: 'qiut ',
Foo: test
}

Obj. foo ();

// 'Qiutc'
It remains unchanged because everything in js is an object, and a function is also an object.

test

, It is just a function name, a function reference, it points to this function, when

foo = test

,

foo

It also points to this function.

If you assign an object method to a variable and then call the variable directly:

Var obj = {
Name: 'qiut ',
Foo: function (){
Console. log (this );
}
}

Var test = obj. foo;
Test ();

// Window
We can see that at this time

this

The global execution is performed.

test = obj.foo

,

test

Directly pointing to a function reference. In this case

obj

This object does not matter, so it is directly called as a common function. Therefore,

this

Point to a global object.

Pitfalls

We often encounter some pitfalls in the callback function:

Var obj = {
Name: 'qiut ',
Foo: function (){
Console. log (this );
},
Foo2: function (){
Console. log (this );
SetTimeout (this. foo, 1000 );
}
}

Obj. foo2 ();
After executing this code, we will find that

this

Is different:

The first time is

foo2

Directly print

this

, Pointing

obj

This object is beyond doubt;

However

setTimeout

Executed in

this.foo

But it points to a global object. Isn't it used as a function? This is often confusing for beginners;

In fact,

setTimeout

It is just a function, and the function may need parameters.

this.foo

Passed as a parameter

setTimeout

This function, just as it needs

fun

Parameter. During parameter input, this operation is actually performed.

fun = this.foo

.

fun

Point

this.foo

Is actually executed.

fun()

Therefore

obj

It is called directly as a common function. Therefore

this

Point to a global object.

This problem is common in many asynchronous callback functions;

Solution

To solve this problem, we can use the closure feature to handle it:

Var obj = {
Name: 'qiut ',
Foo: function (){
Console. log (this );
},
Foo2: function (){
Console. log (this );
Var _ this = this;
SetTimeout (function (){
Console. log (this); // Window

Console. log (_ this); // Object {name: "qiutc "}
},1000 );
}
}

Obj. foo2 ();
You can see that

this

Still yes

Window

Because

foo2

In

this

Yes

obj

, We can use a variable

_this

And then use it in the callback function.

_this

To point to the current object;

Another pitfall of setTimeout

Previously, if the callback function is directly executed without binding the scope

this

Is a Global Object (

window

In strict mode.

undefined

However

setTimeout

The callback functions in strict mode are different:

'Use strict ';

Function foo (){
Console. log (this );
}

SetTimeout (foo, 1 );

// Window
The strict mode is added, and the foo call is not specified.

this

, It should be

undefined

But there are still global objects. Is the strict mode invalid?

No, even in strict mode,

setTimeout

Method when calling the input function, if this function is not specified

this

Then it performs an implicit operation -- automatically injects the global context, which is equivalent to calling

foo.apply(window)

Rather

foo()

;

Of course, if we have specified

this

So that global objects are not injected, such:

setTimeout(foo.bind(obj), 1);
Used as a constructor

In js, to implement classes, we need to define some constructors. When calling a constructor, we need to add

new

This Keyword:

Function Person (name ){
This. name = name;
Console. log (this );
}

Var p = new Person ('qiut ');

// Person {name: "qiutc "}
We can see that when called as a constructor,

this

Points to the object instantiated during the call of this constructor;

Of course, constructor is actually a function. If we treat it as a normal function, this

this

Still execute Global:

Function Person (name ){
This. name = name;
Console. log (this );
}

Var p = Person ('qiut ');

// Window
The difference is that how to call a function (

new

).

Arrow Function

In the new ES6 specification, an arrow function is added, which is the most different from a common function.

this

We still remember to use the closure to solve this problem.

this

If the arrow function is used, the problem can be solved more perfectly:

Var obj = {
Name: 'qiut ',
Foo: function (){
Console. log (this );
},
Foo2: function (){
Console. log (this );
SetTimeout () => {
Console. log (this); // Object {name: "qiutc "}
},1000 );
}
}

Obj. foo2 ();
As you can see

setTimeout

In the executed function, it should have been printed in

Window

But here

this

But points

obj

The reason is:

setTimeout

The input function (parameter) is an arrow function:

This object in the function body is the object in the definition, rather than the object in use.


Based on the example, we can understand this sentence:

In

obj.foo2()

During execution, the current

this

Point

obj

; In execution

setTimeout

First, we define an anonymous arrow function. The key point is here.

this

The object in which the definition is executed refers to the objects in the scope when the arrow function is defined.

this

, That is

obj.foo2

In

this

, That is

obj

So when executing the arrow function, its

this

->

This in obj. foo2

->

obj

;

In simple terms, this in the arrow function is only related to the scope of this when it is defined, and has nothing to do with where and how to call it. At the same time, its this point cannot be changed.

Call, apply, bind

In js, functions are also objects, and there are also some methods. Here we will introduce three methods, they can change

this

Point:

Call
Fun. call (thisArg [, arg1 [, arg2 [,...])

It will immediately execute the function. The first parameter is to specify the execution function

this

The following parameters are the parameters that need to be passed in to the execution function;

Apply
Fun. apply (thisArg [, [arg1, arg2,...])

It will immediately execute the function. The first parameter is to specify the execution function

this

The second parameter is an array, which is the parameter passed to the execution function (

call

);

Bind
Var foo = fun. bind (thisArg [, arg1 [, arg2 [,...]);

Instead of executing the function, it returns a new function, which is specified

this

The following parameters are the parameters that need to be passed in to the execution function;

These three functions are similar in fact. The general purpose is to specify the context (this) of a function.

call

The function is used as an example;

Specify this for a Common Function

Var obj = {
Name: 'qiutc'
};

Function foo (){
Console. log (this );
}

Foo. call (obj );

// Object {name: "qiutc "}
As you can see

foo.call(obj)

In the Function

this

Pointed

obj

This object is successful;

Specify

Var obj = {
Name: 'qiut ',
Foo: function (){
Console. log (this );
}
}

Var obj2 = {
Name: 'tcqiu22222222'
};

Obj. foo. call (obj2 );

// Object {name: "tcqiu222222 "}
We can see that during function execution

this

Pointed

obj2

, Succeeded;

Specify this for the constructor

Function Person (name ){
This. name = name;
Console. log (this );
}

Var obj = {
Name: 'qiutc2222222'
};

Var p = new Person. call (obj, 'qiutc ');

// Uncaught TypeError: Person. call is not a constructor (...)
An error is reported because

new

Now

Person.call

Function, rather

Person

, The function here is not a constructor;

Change

bind

Try:

Function Person (name ){
This. name = name;
Console. log (this );
}

Var obj = {
Name: 'qiutc2222222'
};

Var Person2 = Person. bind (obj );

Var p = new Person2 ('qiut ');

// Person {name: "qiutc "}

Console. log (obj );

// Object {name: "qiutc2222222 "}
The output is

Person

And

obj

It doesn't matter, and

obj

No changes.

Person

Specify

this

The context does not take effect;

Therefore, we can conclude that bind is used to specify a constructor.

this

, In

new

During this constructor,

bind

The

this

Does not take effect;

Of course

bind

You can specify

this

You can also input parameters. Let's try this operation:

Function Person (name ){
This. name = name;
Console. log (this );
}

Var obj = {
Name: 'qiutc2222222'
};

Var Person2 = Person. bind (obj, 'qiutc11111111 ');

Var p = new Person2 ('qiut ');

// Person {name: "qiutc111111 "}
As you can see, although

this

Does not work, but the input parameter still works;

Specify this for the arrow Function

Define a global arrow function.

this

It will inevitably point to the global object.

call

Method change

this

What about:

Var afoo = (a) => {
Console. log ();
Console. log (this );
}

Afoo (1 );

// 1
// Window

Var obj = {
Name: 'qiutc'
};

Afoo. call (obj, 2 );

// 2
// Window
We can see that

call

Point

this

The operation is not successful, so it can be concluded that this in the arrow function has decided when defining it (executing this in its scope ), it has nothing to do with how to call and where to call it, including (call, apply, bind) and other operations. this cannot be changed.

Just remember the arrow function.

this


The above is the detailed description of this in JavaScript. For more information, see other related articles in the first PHP community!

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.