不同情况下,this的指向
- 严格模式,指向undefine
- node环境下,指向{}
- 构造函数内部this指向,指向它的实例对象
- 函数内部this指向调用它的对象
- 箭头函数没有自己的this,取它外层的this
构造函数举例
迷惑性this
例子一:普通函数调用时可能会出现的问题
var publicName = 'Maic'; // var 定义,实际上等同于window.publicName = publicName\
const userInfo = {
publicName: 'Jack',
getName: function(){
console.log(this.publicName, '---useInfo')
}
}
var user = userInfo.getName;
user()
//这里this指向window
var obj=userInfo.getName
obj()// Maic
为啥这里this指向window呢,可以通过以下代码理解一下
// var user = userInfo.getName; 等价于以下代码
window.user = function(){
console.log(this.publicName, '---useInfo')
}
例子二:箭头函数this
var name = "Maic";
...
var user = {
name: 'Jack',
a: {
name: 'Tom',
b: () => {
console.log(this.name)
}
}
}
console.log(user.a.b()) // Maic
为啥不是显示Jack呢,通过以下babel转换后的代码可以理解一下
var _this = this;
var user = {
name: "Jack",
a: {
name: "Tom",
b: function b() {
console.log(_this.name);
}
}
};
例子三:对象嵌套中调用函数
var nobj = {
name: '1',
a: {
name: '2',
b: {
name: '3',
c: function () {
console.log(this.name)
}
}
}
}
console.log(nobj.a.b.c()); //3 这里是因为直接调用c的是b,c中的this指向b
做个面试题
var obj = {
a: 1,
b: function () {
console.log(this.a)
},
c: () => {
console.log(this.a)
}
}
var a = 2;
var objb = obj.b;
var objc = {
a: 3
}
objc.b = obj.b;
const t = objc.b;
let v= objc.b;
// 依次写出答案
obj.b();
obj.c();
objb();
objc.b();
obj.b.call(null);
obj.b.call(objc);
t()
v()
答案在下一个代码块
obj.b(); //1 obj直接调用b,this指向obj
obj.c(); //2 箭头函数中的this指向window
objb(); //2 例子二中的情形 相当于在window环境中执行
objc.b(); //3 objc直接调用函数,this指向objc
obj.b.call(null); //2 call中给的参数是null或者undefined 的话相当于 call(window)
obj.b.call(objc); //3 用call改变this指向为objc
t() // 2 const定义的在编译以后变成var 相当于在window下挂载了
v() //2 let 定义的在编译以后变成var 相当于在window下挂载了