# h1[學習筆記] this 作用域
```javascript=
const obj = {
name: 'Andy',
getName: function() {
console.log(this.name)
}
}
const foo = obj.getName
obj.getName()
foo()
```
用 this 擺在哪的觀念來思考:
1. 對於 `obj.getName()` 來說,這就是進行**物件內部**的操作,這時候的 `this` 不是 `window` 而是**物件本身**,所以這時候的 `this.name` 其實就是 `obj.name` 也因此 `obj.getName()` 會輸出正確的值。 *// 輸出 'Andy'*
1. 對於 `foo()` 來說它就只是個單純的 `function() { console.log(this.name) }` ,所以這時候的 `this.name` 其實就是 `window.name` 的意思,我們也沒有宣告任何全域變數所以會輸出 `undefined` 也是正常的。 *// 輸出 undefined*
---
像剛剛說的,如果我先把 window 的 name 定義好的話,這樣會怎麼樣的結果呢?
```javascript=
window.a = 1
const obj = {
a: 10,
show: function() {
console.log(this.a) // 輸出?
function foo() {
console.log(this.a) // 輸出?
}
foo()
}
}
obj.show()
```
1. 第一個 this.a 會跑出 obj.a 的值。 *//10*
2. 第二個 this.a 因為他找不到 foo 裡面的 this.a ,所以他就會往全域去找,加上一開始就定義了 window.a = 1 ,所以他抓到
---
### 常見 this 作法
* **call** (this, 參數1, 參數2, …)
使用給定的 this 讓其他 function 也可以收到不同於自身的 this 以及參數,舉例來說。
```javascript=
const obj = {
name: 'Andy'
}
const obj2 = {
name: 'andy',
getName: function(age) {
console.log(this.name, age)
}
}
obj2.getName(18) // 輸出 'andy' 18
obj2.getName.call(obj, 18) // 輸出 'Andy' 18
```
* **apply** (this, [參數1, 參數2, …])
基本上跟 call() 一模一樣,差別只在於 apply() 不能傳入多個參數,參數必須要用陣列包起來。
```javascript=
const obj = {
name: 'Andy'
}
const obj2 = {
name: 'andy',
getName: function(age) {
console.log(this.name, age)
}
}
obj2.getName(18) // 輸出 'andy' 18
obj2.getName.apply(obj, [18]) // 輸出 'Andy' 18
```
* **bind** (this, 參數1, 參數2, …)
基本上跟 call() 還有 apply() 一模一樣但差別是 bind() 會回傳一個綁定 **this** 過後的 **function** ,不像 call() 跟 apply() 是不會回傳 **function** 的,而 bind() 本身也可以接受多個參數。
```javascript=
const obj = {
name: 'Andy'
}
const obj2 = {
name: 'andy',
getName: function(age) {
console.log(this.name, age)
}
}
const foo = obj2.getName.bind(obj, 18)
obj2.getName(18) // 輸出 'andy' 18
foo() // 輸出 'Andy' 18
```
---
### Arrow Function 的 this
```javascript=
const obj = {
name: 'Andy',
getName: () => console.log(this.name)
}
obj.getName() // 輸出?
```
正確答案是 `undefined` 。
#### 因為 arrow function 自己沒有 `this` 。
可是呢?如果是這樣的話,會是什麼結果呢?
```javascript=
const obj = {
a: 10,
show: function() {
console.log(this.a)
return () => console.log(this.a)
}
}
const foo = obj.show()
foo()
```
要先釐清 obj.show() 是不是箭頭函示。
如果不是的話我們可以再往裡面看,箭頭函式`return () => console.log(this.a)}`定義在普通函式` show: function()`中。
所以其 this 繼承自 obj.show() 的 this,也就是 obj 物件。
文章來源:https://medium.com/andy-blog/day25-this%E4%BD%9C%E7%94%A8%E5%9F%9F-b5db33487aab