函数内部this指向问题

函数内部this指向问题

四月 13, 2019

this是一个对象,是在函数运行的时候基于函数的运行环境绑定的

关于this指向的问题,可以简单的概括一句话:谁调用我,我就指向谁

this指向问题

在不同的场景下this的指向会不太一样,例如:

普通函数内部this指向window

严格模式下this指向undefined,在函数内部执行:console.log(this),控制台会输出undefined

非严格模式下,this指向window,就是在window下调用了这个函数

1
2
3
4
5
6
7
8
9
// 普通函数中,this指向window
function a() {
console.log(this); // Window {window: Window, self: Window, document: document, name: "", location: Location, …}
function aa() {
console.log(this); // Window {window: Window, self: Window, document: document, name: "", location: Location …}
}
aa()
}
a();

在对象的方法中this指向这个对象

通过对象成员访问‘.’的方式调用,this指向这个对象,也就是这个对象调用了这个方法,所以这个方法的this指向这个对象

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
sayHi:function() {
console.log(this); // 在对象的方法中,指向sayHi对象
function fn1() {
console.log(this); // window,this指向window,是因为这个函数是一个普通的函数,并不少某个对象的方法
}
fn1();
return function () {
console.log(this) // 闭包window
}
}
};
obj.sayHi();

在定时器中指向window

1
2
3
setTimeout(function(){
console.log(this); // window
},0);

在构造函数中

1
2
3
4
function Person() {
console.log(this); // 指向实例对象:Person{}
}
new Person();

在事件处理函数中指向

指向绑定事件的对象

1
2
3
input.onclick = function() {
console.log(this); // 绑定事件对象
};

在匿名函数中指向window

1
2
3
(function () {
console.log(this) //window
})()

改变this的指向

call

func.call(调用者,参数1,参数2)

调用的时候函数会被立即执行,函数体内的this指向调用者

1
2
3
4
5
6
7
8
var obj = {
name: 'xinxin',
}
function b (name) {
this.name = name;
console.log(this)
}
b.call(obj, 'lll'); // this指向调用者:obj

apply

func.apply(调用者, [参数1,...])

调用的时候函数会被立即执行,函数体内的this指向调用者

1
2
3
4
5
6
7
8
var obj = {
name: 'xinxin',
}
function b (name) {
this.name = name;
console.log(this)
}
b.call(obj, ['111']); // this指向调用者:obj

bind方法

func.bind(调用者,参数1,参数2)

调用的时候函数不会被立即执行,返回一个新的函数,函数体内的this指向调用者,需要手动调用新的函数

1
2
3
4
5
6
7
8
9
var obj = {
name: 'xinxin',
}
function b (name) {
this.name = name;
console.log(this)
}
const bb = b.bind(obj, 'lll'); //this指向obj
bb();

为什么内部函数和匿名函数没有取得外部包含作用域的this对象呢

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
sayHi:function() {
console.log(this); // 在对象的方法中,指向sayHi对象
function fn1() {
console.log(this); // window
}
fn1();
return function () {
console.log(this) // 闭包window
}
}
};
obj.sayHi();

在函数被调用的时候,会自动获取两个特殊的对象:arguments和this,内部函数在搜索这两个变量的时候,只会搜索到其活动对象位置,因此永远不能访问外部函数中的这两个对象。