---
# System prepended metadata

title: 範圍鏈 Scope Chain
tags: [Javascript]

---

# 範圍鏈 Scope Chain

###### tags: `Javascript`

解析下方範例:

1. 呼叫outer(a)帶入參數a 進去outer()內部
2. 看到outer()內部呼叫inner(b*3)
3. 進入inner(c)內部，印出a,b,c
4. 此時已知 c = 6因為 a=1, b=a*2=2, c=b*3=6
5. 但是b,c必須往外找在inner()的外面找到b
6. 在outer()外面找到a
7. 印出 1, 2, 6


```javascript=
function outer() {

  var b = a * 2;
  
  function inner(c) {
    console.log(a, b, c);
  }
  inner(b * 3);
}

var a = 1;
outer(a);
```

從上面範例可以看出在inner()內部是找不到a,b變數的，因為往外去尋找，而這個往外尋找的動作就稱為範圍鏈


## 練習題

這邊result印出結果是什麼呢?

```javascript=
var msg = "global."

function outer() {
  var msg = "local."

  function inner() {
    return msg;
  }

  return inner;
}

var innerFunc = outer();
var result = innerFunc();

console.log( result );    //  ?
```

1. 先看result等於innerFunc()
2. 再看到innerFunc()等於outer()
3. 看到outer()內，return inner()
4. 看到inner()內，return msg
5. 這邊因為inner內部找不到變數msg所以往外找找到了 = local.
6. 故印出local.

這題的考點是:

1. 外部環境的連結是在函式宣告當下就決定了而不是在呼叫的時候
2. 所以 inner 的外層就是 outer 也就可以在這找到 msg 變數



> 當內部 (inner) 函式被回傳後，除了自己本身的程式碼外，也可以 穿越 取得了內部函式「當時環境」的變數值，記住了執行當時的環境，這就是「閉包」。