讲给自己听的白话版 this 指向

111 阅读2分钟

近日准备面试,苦于 this 指向问题没搞清楚;查阅过后简单总结一下:

  1. 普通函数 this 指向与函数的调用者密切相关;this 总是指向函数的调用者;
  • 普通函数,this 指向全局window
  • 立即执行函数中,this 指向全局 window
  • 定时器函数中,this 指向全局 window
  • 构造函数中,this 指向 new 出来的实例化对象
  • 对象中,this 指向该函数所属的对象
  • dom 节点绑定事件中,this 指向绑定事件 dom 节点对象
  1. 箭头函数 this 指向仅仅是发生在定义时候,后续不可再修改;
  • 定义箭头函数的时候,若外部有普通函数包裹则 this 指向与外部普通函数 this 指向一致,
  • 若没有则默认指向 window

上例子简单解释以上两点

  const func = function(){
    console.log(this);
  }
  func() // window 直接调用,this 指向 window
  

  let obj = {
    x:1,
    func:function(){
      console.log(this); // obj func 被 obj 调用 this 指向 obj
      (()=>{
        console.log(this); // obj  箭头函数,外部存在函数 this 指向与外部函数指向一致;外部函数 this 指向 obj
      })()  

      const func1 = function(){
        console.log('func1',this);// window 直接调用,this 指向 window
        (()=>{
        console.log('func1箭头函数',this); //   箭头函数,外部存在函数 this 指向与外部函数指向一致;外部函数 this 指向 window
      })()  
      }
      func1()
    },
    func1:()=>{
      console.log(this); // window 箭头函数,外部没有函数包裹 this 指向 window
    }
  }
  obj.func()
  obj.func1()


const func1 = function(){
  const func2 = function(){
    console.log(this);//直接调用,this 指向 window
    const func3 = function(){
      console.log(this);//直接调用,this 指向 window
    }
    func3()
  }
  func2()
}
func1()

更改this指向方法

bind、call、apply

  • call 第一个参数为绑定对象,后续为函数参数
function fn(val, num) {
    this.val = val;
    this.num = num;
}
const obj1 = {}
// 经过call,this指向obj1,obj1开始有val、num属性
fn.call(obj1, '修改this指向', 100)
console.log(obj1);
// 以下this均指向window,val:undefined,num:undefined
fn.call()
fn.call(null)
fn.call(undefined)

  • bind 返回一个函数,需要添加 () 执行;且只会绑定一次:链式bind 只认第一次绑定的对象
function fn(val, num) {
    this.val = val;
    this.num = num;
}
const obj1 = {}
fn.bind(obj1, '修改this指向', 100)()
  • apply ,第一个参数为绑定对象,后续参数通过数组传入
function fn(val, num) {
    this.val = val;
    this.num = num;
}
const obj1 = {}
// 经过apply,this指向obj1,obj1开始有val、num属性
fn.apply(obj1, ['修改this指向', 100])
// 以下this均指向window,val:undefined,num:undefined
fn.apply()
fn.apply(null)
fn.apply(undefined)