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()) // hello

function內 this的值則指向呼叫function的東西,在下方範例中也就是window本身

1
2
3
4
5
function hello(){
console.log(this)
}

hello()

在這種情況下this的指向:

  1. 嚴格模式底下就都是undefined1. 嚴格模式底下就都是undefined
  2. 非嚴格模式,瀏覽器底下是window
  3. 非嚴格模式,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) // yo 1 2
hello.apply('hihihi', [1, 2]) // 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 instance
myCar.hello.call('yaaaa') // 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() // my
myHello.call('call') // my

直接創造的物件中的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

印出結果: 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() // 1
const hey = obj.hello
hey() // undefined

解法:

把所有的 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() // 1
obj.hello.call(obj) // 轉成 call
const hey = obj.hello
hey() // undefined
hey.call() // 轉成 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 () {
// 這邊印出來的 this 是什麼,test 的 this 就是什麼
// 就是我說的:
// 在宣告它的地方的 this 是什麼,test 的 this 就是什麼
console.log(this)
const test = () => {
console.log(this.x)
}
test()
}
}

// obj.hello() // 1
const hello = obj.hello
hello() // undefined