一句話概括就是: 箭頭函數(shù)的this與創(chuàng)建時的封閉詞法上下文的this保持一致。
箭頭函數(shù)的這種表現(xiàn)形式的本質(zhì)是函數(shù)創(chuàng)建機(jī)制造成的特纤,由于箭頭函數(shù)沒有this變量,在函數(shù)解析的時候侥加,發(fā)現(xiàn)內(nèi)部引用了this捧存,則會在作用域鏈中記錄this所在的活動對象。如果最近一個封閉詞法上下文是函數(shù),則會形成一個閉包昔穴。當(dāng)函數(shù)執(zhí)行時镰官,就會取出scope中的這個this值。這也解釋了為什么this與創(chuàng)建時的封閉詞法上下文保持一致吗货,而不是調(diào)用時泳唠。
function bar() {
const foo = () => this
// true
console.log(foo() === this)
// [[scope]][0] = Closure (bar) {type: "closure", name: "bar", object: {…}}
console.log({foo})
}
bar()
準(zhǔn)確一點(diǎn)說應(yīng)該是,箭頭函數(shù)沒有自己的this以及arguments,所能取到的this是它被創(chuàng)建時的封閉詞法上下文宙搬。箭頭函數(shù)使用call,apply,bind傳遞作用域會被忽略, 但是可以用來傳遞參數(shù)笨腥,此時第一個參數(shù)應(yīng)該設(shè)置為null。以下為實(shí)例:
const foo = ((...rest) => { console.log(this) })
let foo1 = foo.bind({demo: 1}, 'demo')
// window
foo1()
function Foo() {
// Foo 實(shí)例
console.log(this)
this.obj = {
// window
foo: foo,
// obj
bar() { console.log(this) },
// Foo實(shí)例
zoo: () => { console.log(this) },
callF() { this.foo(), this.bar(), this.zoo() }
}
}
let demo = new Foo()
demo.obj.callF()