this 是什麼
在物件內this就會導向物件本身,比較簡單好懂
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Car { setName(name) { this.name = name } getName() { return this.name } } const myCar = new Car() myCar.setName('hello') console.log(myCar.getName())
|
function內 this的值則指向呼叫function的東西,在下方範例中也就是window本身
1 2 3 4 5
| function hello(){ console.log(this) } hello()
|
在這種情況下this的指向:
- 嚴格模式底下就都是undefined1. 嚴格模式底下就都是undefined
- 非嚴格模式,瀏覽器底下是window
- 非嚴格模式,node.js 底下是global
更改 this 的值
call跟apply
你第一個參數傳什麼,裡面 this 的值就會被其取代
1 2 3 4 5 6 7
| 'use strict'; function hello(a, b){ console.log(this, a, b) } hello.call('yo', 1, 2) hello.apply('hihihi', [1, 2])
|
就算使用物件讓this指向有明確的目標也會被取代
1 2 3 4 5 6 7 8 9 10
| class Car { hello() { console.log(this) } } const myCar = new Car() myCar.hello() myCar.hello.call('yaaaa')
|
最後一種可以改變 this 的方法:bind
- 把 hello 這個 function 用 my 來綁定,並且呼叫會輸出my
- 並且使用
.call()
來改變其值也不會改變
1 2 3 4 5 6 7 8
| 'use strict'; function hello() { console.log(this) } const myHello = hello.bind('my') myHello() myHello.call('call')
|
直接創造的物件中的this
沒有透過class或是new關鍵字因此記得
this 的值跟作用域跟程式碼的位置在哪裡完全無關,只跟「你如何呼叫」有關
1 2 3 4 5 6 7 8
| const obj = { value: 1, hello: function() { console.log(this.value) } } obj.hello()
|
印出結果: 1 , = obj本身的value = 呼叫的對象本身
問題來了
這邊的hey()是同一個函式卻跑出不同的結果?
1 2 3 4 5 6 7 8 9 10
| const obj = { value: 1, hello: function() { console.log(this.value) } } obj.hello() const hey = obj.hello hey()
|
解法:
把所有的 function call,都轉成利用call的形式來看,以上面那個例子來說,會是這樣:
規則就是你在呼叫 function 以前是什麼東西,你就把它放到後面去
obj.hello()
=> obj.hello.call(obj)
obj.value = 1
hey()
=> hey.call()
空的就填入預設值window.value也就是undefined
1 2 3 4 5 6 7 8 9 10 11 12
| const obj = { value: 1, hello: function() { console.log(this.value) } } obj.hello() obj.hello.call(obj) const hey = obj.hello hey() hey.call()
|
箭頭函式中的this
它本身並沒有 this,所以「在宣告它的地方的 this 是什麼,它的 this 就是什麼」
箭頭函式被宣告的地方的this是什麼,箭頭函式的this就是一樣的東西:
所以範例處hello的this是obj那箭頭函式的this就是obj
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const obj = { x: 1, hello: function () { console.log(this) const test = () => { console.log(this.x) } test() } }
const hello = obj.hello hello()
|