js中的this指向

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
var Obj = function(msg){
this.msg = msg;
this.shout = function(){
console.log(this.msg);
}
this.waitAndShout = function(){
setTimeout(function () {
this.shout();
}.call(this),200);
}
};
var obj = new Obj('haha');
obj.waitAndShout();

obj对象调用了waitAndShout,所以waitAndShout中的this指向obj,而setTimeout第一个参数的函数thiscall指向了外层作用域的对象,即obj对象,所以打印出haha。这里如果不加.call(this),就会报错this.shout is not a function

核心

this永远指向最后调用它的对象(其上一级对象);
函数没有被其上一级对象调用,其this指向window,严格模式下指向undefined;
函数被其上一级对象调用,其this指向其上一级对象。

特殊情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function fn()  
{
this.user = 'Hank';
return {};
}
var a = new fn;
console.log(a.user); //undefined

function fn()
{
this.user = 'Hank';
return undefined;
}
var a = new fn;
console.log(a.user); //Hank

如果返回值是一个对象(非 null ),那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。

ES6中箭头函数的this指向

箭头函数的this指向定义时所在的作用域,而不是运行时所在的作用域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var obj2 = {
id: 2333,
test: () => console.log(this)
}
obj2.test() // Window

var obj3 = {
id: 2333,
test: function () {console.log(this)}
}
obj3.test() // obj3

// 改成ES5写法如下
var obj2 = {};
obj2.id = 2333;
var _this = this;
obj2.test = function(){console.log(_this);}

此时_this的指向已经确定好了,无论使用任何call或者apply调用,都不会改变_this的值。