物件導向裡面的 this
- 物件導向裡面的 this 是欲存取的 instance
- 哪一個 instance call function,this 就是哪一個 instance。
在非物件導向的情況下,this 會是什麼?
非嚴格模式下
- node.js 上的 this 為 global
- 瀏覽器上的 this 為 window
嚴格模式下皆為 undefined
'use strict'
function test() {
console.log(this) // undefined
}
test()
在 addEventListener 裡的 this
實際操作到的就是 this
<button class="btn">我是按鈕</button>
<script>
document
.querySelector('.btn')
.addEventListener('click', function() {
alert(this) //[object HTMLButtonElement]
})
</script>
傳什麼給 call,第一個參數值就是 this
'use strict'
function test() {
console.log(this) // Number: 123
}
test.call(123)
call 跟 apply 的差異
- call 可傳多個參數
- apply 第二個參數必須是 array
'use strict'
function test(a, b, c) {
console.log(this)
console.log(a, b, c)
}
test.call(123, 1, 2, 3)
// Number: 123
// 1 2 3
test.apply(123, [1, 2, 3])
// Number: 123
// 1 2 3
用 call 來理解 this 是什麼
'use strict'
const obj = {
a: 123,
inner: {
test: function() {
console.log(this)
}
}
}
obj.inner.test() // { test: f }
obj.inner.test.call(obj.inner) // { test: f }
轉成 .call() 的形式
const func = obj.inner.test
func() => func.call(undefined)
obj.inner.test => obj.inner.test.call(obj.inner)
obj.test => obj.test.call(obj)
總結:不同 case 下,this 是什麼?
- 在非物件導向下
- 嚴格模式 ('use strict'):this 為 undefined
- 非嚴格模式:根據 runtime 決定;node.js 為 global,瀏覽器上為 window。
- 在物件導向下,this 就是自己的 instance
- 在 addEventListener 下,操作到的東西是 this。
- 在 obj 下,將其轉換為 .call() 的形式,this 是 .call() 內第一個參數。
.bind() 強制綁定 this
- bind 直接綁定 this 是什麼,無法變動
- p.s.:bind 是回傳一個 function,而 call、apply 是直接呼叫。
const obj = {
a: 1,
test: function() {
console.log(this)
}
}
const bindTest = obj.test.bind('555')
bindTest() // 555
arrow function 的 this
非 arrow function
class Test {
run() {
console.log('run this:', this)
setTimeout(function() {
console.log(this)
}, 100)
}
}
const t = new Test()
t.run()
// run this: Test {}
// window
arrow function
- 會用定義好的 this。
- this 跟怎麼呼叫沒有關係,跟哪邊定義有關係。
class Test {
run() {
console.log('run this:', this)
setTimeout(() => {
console.log(this)
}, 100)
}
}
const t = new Test()
t.run()
// run this: Test {}
// Test {}