记录This指向

60 阅读1分钟

不同情况下,this的指向

  • 严格模式,指向undefine
  • node环境下,指向{}
  • 构造函数内部this指向,指向它的实例对象
  • 函数内部this指向调用它的对象
  • 箭头函数没有自己的this,取它外层的this

构造函数举例

image.png

迷惑性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下挂载了