Home > Web Front-end > JS Tutorial > body text

Detailed introduction to the use of this in JavaScript

怪我咯
Release: 2017-03-30 09:20:05
Original
1289 people have browsed it

tip

First of all, I know this article is boring, it is just about this in js, and there are already thousands of them Wan's article has written this part;

However, I still want to write an article about this in js, which can be regarded as a summary; (Masters can go around and read my other articles)

In js, the context of this is always unpredictable. Many times when bugs occur, you are always confused. In fact, as long as you know how to execute it in different situations, it will be ok.

Global execution

First, let’s see what this is in the global environment:

first. Browser:

console.log(this);

// Window {speechSynthesis: SpeechSynthesis, caches: CacheStorage, localStorage: Storage, sessionStorage: Storage, webkitStorageInfo: DeprecatedStorageInfo…}
You can see it printed

window
Copy after login
Copy after login

Object;

second. node:

console.log(this);

// global
Yes See the

global
Copy after login
Copy after login

object printed out;

Summary: In the global scope, its

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

executes the current global object (the browser side is

Window
Copy after login
Copy after login
Copy after login

, node is

global
Copy after login
Copy after login

).

Execute pure function calls in functions

This is the most common way to use functions:

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. At this time, its

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

points to the global object;

##strictly Mode 'use strict';

If a pure function call is executed in strict mode, then the

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

here will not point to the global, but

undefined
Copy after login
Copy after login
Copy after login

, this approach is to eliminate some lax behaviors in js:


'use strict';
function test() {
console.log(this);
};

test();

// undefined
Of course, it would be better to put it in an immediately executed function to avoid polluting the global situation:

(function (){
"use strict";
console.log(this);
})();

// undefined

as an object Method call

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


var obj = {
name: 'qiutc',
foo: function() {
console.log(this.name);
}
}

obj.foo();

// 'qiutc'
At this time,

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Points to the current object;


Of course, we can also do this:

function test() {
console.log(this.name);
}
var obj = {
name: 'qiutc',
foo: test
}

obj.foo();

// ' qiutc'
is also unchanged, because everything in js is an object, and a function is also an object. For

test
Copy after login
Copy after login

, it is just a function name, and the

reference of the function points to This function, when

foo = test
Copy after login

,

foo
Copy after login

also points to this function.


What if you assign the object's method to a
variable and then call this variable directly:
var obj = {
name: 'qiutc',
foo: function() {
console.log(this);
}
}

var test = obj.foo;
test();

// Window
You can see that

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

executes the global function at this time. When we point

test = obj.foo
Copy after login

and

test
Copy after login
Copy after login

directly to a reference to a function, At this time, it actually has nothing to do with the object

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

, so it is called directly as an ordinary function. Therefore,

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

points to the global object.



Some pitfalls

We often encounter some pitfalls in the

callback function:
var obj = {
name: 'qiutc',
foo: function() {
console.log(this);
},
foo2: function() {
console.log(this);
setTimeout(this.foo, 1000);
}
}

obj.foo2();
When we execute this code, we will find that it is printed twice

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

is different:


The first time is to print

foo2
Copy after login
Copy after login

directly in

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

, which points to the object

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

, we Undoubtedly;


but
executed in

setTimeout
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

this.foo
Copy after login
Copy after login
Copy after login

,却指向了全局对象,这里不是把它当作函数的方法使用吗?这一点经常让很多初学者疑惑;

其实,

setTimeout
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

也只是一个函数而已,函数必然有可能需要参数,我们把

this.foo
Copy after login
Copy after login
Copy after login

当作一个参数传给

setTimeout
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

这个函数,就像它需要一个

fun
Copy after login
Copy after login

参数,在传入参数的时候,其实做了个这样的操作

fun = this.foo
Copy after login

,看到没有,这里我们直接把

fun
Copy after login
Copy after login

指向

this.foo
Copy after login
Copy after login
Copy after login

的引用;执行的时候其实是执行了

fun()
Copy after login

所以已经和

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

无关了,它是被当作普通函数直接调用的,因此

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

指向全局对象。

这个问题是很多异步回调函数中普遍会碰到的;

解决

为了解决这个问题,我们可以利用 闭包 的特性来处理:

var obj = {
name: 'qiutc',
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();
可以看到直接用

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

仍然是

Window
Copy after login
Copy after login
Copy after login

;因为

foo2
Copy after login
Copy after login

中的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

是指向

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

,我们可以先用一个变量

_this
Copy after login
Copy after login

来储存,然后在回调函数中使用

_this
Copy after login
Copy after login

,就可以指向当前的这个对象了;

setTimeout 的另一个坑

之前啊说过,如果直接执行回调函数而没有绑定作用域,那么它的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

是指向全局对象(

window
Copy after login
Copy after login

),在严格模式下会指向

undefined
Copy after login
Copy after login
Copy after login

,然而在

setTimeout
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

中的回调函数在严格模式下却表现出不同:

'use strict';

function foo() {
console.log(this);
}

setTimeout(foo, 1);

// window
按理说我们加了严格模式,foo 调用也没有指定

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

,应该是出来

undefined
Copy after login
Copy after login
Copy after login

,但是这里仍然出现了全局对象,难道是严格模式失效了吗?

并不,即使在严格模式下,

setTimeout
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

方法在调用传入函数的时候,如果这个函数没有指定了的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

,那么它会做一个隐式的操作—-自动地注入全局上下文,等同于调用

foo.apply(window)
Copy after login

而非

foo()
Copy after login



当然,如果我们在传入函数的时候已经指定

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

,那么就不会被注入全局对象,比如:

setTimeout(foo.bind(obj), 1);
Copy after login

作为一个构造函数使用

在 js 中,为了实现类,我们需要定义一些构造函数,在调用一个构造函数的时候需要加上

new
Copy after login
Copy after login
Copy after login
Copy after login

这个关键字:

function Person(name) {
this.name = name;
console.log(this);
}

var p = new Person('qiutc');

// Person {name: "qiutc"}
我们可以看到当作构造函数调用时,

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

指向了这个构造函数调用时候实例化出来的对象;

当然,构造函数其实也是一个函数,如果我们把它当作一个普通函数执行,这个

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

仍然执行全局:

function Person(name) {
this.name = name;
console.log(this);
}

var p = Person('qiutc');

// Window
其区别在于,如何调用函数(

new
Copy after login
Copy after login
Copy after login
Copy after login

)。

箭头函数

在 ES6 的新规范中,加入了箭头函数,它和普通函数最不一样的一点就是

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

的指向了,还记得我们使用闭包来解决

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

的指向问题吗,如果用上了箭头函数就可以更完美的解决了:

var obj = {
name: 'qiutc',
foo: function() {
console.log(this);
},
foo2: function() {
console.log(this);
setTimeout(() => {
console.log(this); // Object {name: "qiutc"}
}, 1000);
}
}

obj.foo2();
可以看到,在

setTimeout
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

执行的函数中,本应该打印出在

Window
Copy after login
Copy after login
Copy after login

,但是在这里

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

却指向了

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

,原因就在于,给

setTimeout
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

传入的函数(参数)是一个箭头函数:

函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
Copy after login


根据例子我们理解一下这句话:

obj.foo2()
Copy after login

执行的时候,当前的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

指向

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

;在执行

setTimeout
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

时候,我们先是定义了一个匿名的箭头函数,关键点就在这,箭头函数内的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

执行定义时所在的对象,就是指向定义这个箭头函数时作用域内的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

,也就是

obj.foo2
Copy after login

中的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

,即

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

;所以在执行箭头函数的时候,它的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

->

obj.foo2 中的 this
Copy after login

->

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login



简单来说, 箭头函数中的 this 只和定义它时候的作用域的 this 有关,而与在哪里以及如何调用它无关,同时它的 this 指向是不可改变的。

call, apply, bind

在 js 中,函数也是对象,同样也有一些方法,这里我们介绍三个方法,他们可以更改函数中的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

指向:

call
fun.call(thisArg[, arg1[, arg2[, ...]]])

它会立即执行函数,第一个参数是指定执行函数中

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

的上下文,后面的参数是执行函数需要传入的参数;

apply
fun.apply(thisArg[, [arg1, arg2, ...]])

它会立即执行函数,第一个参数是指定执行函数中

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

的上下文,第二个参数是一个数组,是传给执行函数的参数(与

call
Copy after login
Copy after login
Copy after login
Copy after login

的区别);

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

它不会执行函数,而是返回一个新的函数,这个新的函数被指定了

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

的上下文,后面的参数是执行函数需要传入的参数;

这三个函数其实大同小异,总的目的就是去指定一个函数的上下文(this),我们以

call
Copy after login
Copy after login
Copy after login
Copy after login

函数为例;

为一个普通函数指定 this

var obj = {
name: 'qiutc'
};

function foo() {
console.log(this);
}

foo.call(obj);

// Object {name: "qiutc"}
可以看到,在执行

foo.call(obj)
Copy after login

的时候,函数内的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

指向了

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

这个对象,成功;

为对象中的方法指定一个 this

var obj = {
name: 'qiutc',
foo: function () {
console.log(this);
}
}

var obj2 = {
name: 'tcqiu222222'
};

obj.foo.call(obj2);

// Object {name: "tcqiu222222"}
可以看到,执行函数的时候这里的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

指向了

obj2
Copy after login

,成功;

为构造函数指定 this

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(…)
这里报了个错,原因是我们去

new
Copy after login
Copy after login
Copy after login
Copy after login

Person.call
Copy after login

函数,而非

Person
Copy after login
Copy after login
Copy after login

,这里的函数不是一个构造函数;

换成

bind
Copy after login
Copy after login
Copy after login

试试:

function Person(name) {
this.name = name;
console.log(this);
}

var obj = {
name: 'qiutc2222222'
};

var Person2 = Person.bind(obj);

var p = new Person2('qiutc');

// Person {name: "qiutc"}

console.log(obj);

// Object {name: "qiutc2222222"}
打印出来的是

Person
Copy after login
Copy after login
Copy after login

实例化出来的对象,而和

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

没有关系,而

obj
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

也没有发生变化,说明,我们给

Person
Copy after login
Copy after login
Copy after login

指定

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

上下文并没有生效;

因此可以得出: 使用 bind 给一个构造函数指定

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

,在

new
Copy after login
Copy after login
Copy after login
Copy after login

这个构造函数的时候,

bind
Copy after login
Copy after login
Copy after login

函数所指定的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

并不会生效;

当然

bind
Copy after login
Copy after login
Copy after login

不仅可以指定

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

,还能传入参数,我们来试试这个操作:

function Person(name) {
this.name = name;
console.log(this);
}

var obj = {
name: 'qiutc2222222'
};

var Person2 = Person.bind(obj, 'qiutc111111');

var p = new Person2('qiutc');

// Person {name: "qiutc111111"}
可以看到,虽然指定

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

不起作用,但是传入参数还是起作用了;

为箭头函数指定 this

我们来定义一个全局下的箭头函数,因此这个箭头函数中的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

必然会指向全局对象,如果用

call
Copy after login
Copy after login
Copy after login
Copy after login

方法改变

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

呢:

var afoo = (a) => {
console.log(a);
console.log(this);
}

afoo(1);

// 1
// Window

var obj = {
name: 'qiutc'
};

afoo.call(obj, 2);

// 2
// Window
可以看到,这里的

call
Copy after login
Copy after login
Copy after login
Copy after login

指向

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

的操作并没有成功,所以可以得出: 箭头函数中的 this 在定义它的时候已经决定了(执行定义它的作用域中的 this),与如何调用以及在哪里调用它无关,包括 (call, apply, bind) 等操作都无法改变它的 this。

只要记住箭头函数大法好,不变的

this
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login



The above is the detailed content of Detailed introduction to the use of this in JavaScript. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template