首先處理代碼的執行(非箭頭函數)
- 當代碼直接執行
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