天天看点

关于JavaScript this指向

首先处理代码的执行(非箭头函数)

  1. 当代码直接执行
function a() {
	return this;
}
a() 
// 等价于 
a.call(undefined) 
// 严格模式 等于undefined 非严格模式等于window
           
  1. 当函数前有 “.”
let a = {
 	func1: function a () {
		return this
	}
}
a.func1()
// 等价于 
a.func1.call(a)
           

先上代码

var value = 1;
var foo = {
  value: 2,
  bar1: function () {
    return this.value;
  },
  bar2: () => {
    return this.value;
  },
  bar3: () => {
    return function() {
      return this.value
    }
  },
  bar4: function() {
    return () => { return this.value}
  },
  bar5: function() {
    console.log('this', this)
    return function() {
        console.log('inner this', this)
        return this.value;
    }
  }
}
           

运行结果

foo.bar1() // === foo.bar.call(foo)  === 2
foo.bar2()
 // 等价于  foo.bar2.call(foo)  但是 箭头函数不接受this参数, 而是使用申明时候的this ,结果是1
foo.bar3() 
// 等价于 foo.bar3.call(foo)() => foo.bar3.call().call(undefined) => 结果取 window.value => 1 ,如果严格模式将报错 Cannot read property 'value' of undefine
foo.bar4()()
// 等价于 foo.bar4.call(foo)() =>  foo.bar3.call(foo).call(undefine) => 因为第二个函数是箭头函数 所以取第一个call的入参,所以是foo.value => 2
 foo.bar5()()
 // 等价于 foo.bar.call(foo).call(undefined) => 1 严格模式 => Cannot read property 'value' of undefine
           

再举一个例子

document.body.onclick = () => {
    console.log(this)
}
// this === window,因为是箭头函数 不管怎么调用都是window

document.body.onclick = function() {
    console.log(this)
}

// 默认情况下 点击body 相当于执行 
// document.body.onclick() ==> 
// document.body.onclick.call(body) ==> 
// this === body

// 特殊情况
const a = document.body.onclick;
a() // 等价于 a.call(undefined) => this === window => 严格模式等于undefined

           

继续阅读