首先处理代码的执行(非箭头函数)
- 当代码直接执行
function a() {
return this;
}
a()
// 等价于
a.call(undefined)
// 严格模式 等于undefined 非严格模式等于window
- 当函数前有 “.”
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