---
# System prepended metadata

title: this 是什麼
tags: [Javascript]

---

# this 是什麼

###### tags: `Javascript`


在物件內this就會導向物件本身，比較簡單好懂

```javascript=
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本身

```javascript=
function hello(){
  console.log(this)
}
  
hello()
```


在這種情況下this的指向：

1. 嚴格模式底下就都是undefined
1. 非嚴格模式，瀏覽器底下是window
1. 非嚴格模式，node.js 底下是global


# 更改 this 的值

## call跟apply

你第一個參數傳什麼，裡面 this 的值就會被其取代

```javascript=
'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指向有明確的目標也會被取代

```javascript=
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()`來改變其值也不會改變

```javascript=
'use strict';
function hello() {
  console.log(this)
}
  
const myHello = hello.bind('my')
myHello() // my
myHello.call('call') // my
```

# 直接創造的物件中的this

沒有透過class或是new關鍵字因此記得

> this 的值跟作用域跟程式碼的位置在哪裡完全無關，只跟「你如何呼叫」有關

```javascript=
const obj = {
  value: 1,
  hello: function() {
    console.log(this.value)
  }
}
  
obj.hello() // 1
```

印出結果: 1 ， = obj本身的value = 呼叫的對象本身


## 問題來了

這邊的hey()是同一個函式卻跑出不同的結果？

```javascript=
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


```javascript=
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 指向 window

然而 window 並沒有 x 這個變數被宣告(因為他被宣告在 obj 內)

```javascript=
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
```