this指向问题
解题思路
- 普通函数中,this是它的直接调用者,谁调用,this就指向谁。
- 箭头函数,this指向跟外部作用域中this指向是同一个。
面试真题
var a = 1;
function func1(){
var a = 2;
console.log(this.a + a)
}
function func2(){
var a = 10;
func1();
}
func2()
func2指向的是全局,因此this指向的是全局。
var a = 1;
var obj = {
a: 2,
func1: function(){
console.log(this.a);
},
func2: () => {
console.log(this.a);
},
};
obj.func1();
obj.func2();
1.func1是普通函数,所以谁调用就指向谁,obj.func1相当于就是obj调用func1,所以this指向obj,所以obj.func1()输出的是2。
2.func2是箭头函数,箭头函数的this跟外部作用域的this是一致的。func2外部作用域相当于就是obj的作用域,obj中的this指向就是全局的this,所以此时取到的值就是全局的a,值为1。
const obj = {
name: "小明",
say(){
console.log(`你好!$(this.name)`);
},
}
const func = obj.say;
obj.say(); // 你好!小明
func(); // 你好!
setTimeout(obj.say, 100); // 你好!
setTimeout(func, 200); // 你好!
setTimeout(function(){
obj.say(); // 你好!小明
}, 300);
setTimeout(() => obj.say(), 400); // 你好!小明
解析:
- obj.say()直接调用,则是obj调用say,所以this指向obj,则可获取到obj中的name值,故而输出:你好!小明
- func ()在全局调用,所以函数中的this指向的是全局,全局没有name值,所以输出:你好!
- setTimeout(obj.say, 100)中是把obj.say赋值给setTimeout中的第一个参数,并没有通过obj去调用say函数,所以此时内部的this指向的是全局,故而没有name值,输出结果为:你好!
- setTimeout(func, 200)跟3中输出的结果是一样的。都是函数的赋值,并没有真正调用,所以这里的this是setTimeout中的this,setTimeout中的this指向的是全局,故而没有name值,输出结果为:你好!
- 在setTimeout内部函数中,调用了obj.say(), 故而此时this指向调用它的对象obj,所以输出:你好!小明
- 这里的setTimeout中也是obj.say()直接执行调用了,所以谁调用指向谁,故而这里指向obj,输出结果为:你好!小明
参考资料:【JavaScript面试题】this指向问题