# Scope 作用域
###### tags: `單元筆記` `javascript` `觀念`
## 介紹
區分成 Global 、 Function 、 Block 三種,指的是變數或常數的宣告與語句的可被存取得到的範圍。
* Global : 內層所有地方都可以存取這邊的內容,即全域變數
* Function : var 宣告會被限制在內,不影響外層變數
* Block : 就是以大括號 ( {} ) 劃分出作用的範圍,用 let 宣告會被限制在內,不影響外層變數
大概就像這個樣子的大小範圍

## 範例
這邊說明 var 與 let 宣告的作用域,ex01 中 x 並未被限制在大括弧內,他還是可以被存取到,即是在Global Scope 中 ;
而 ex02 有將變數限制在大括弧內,也就是 Block Scope中 ;
然而 ex03 中 x 就有被限制在這個 funtion 內,也就是 Function Scope 中。
* ex01
```javascript=
if (true) {
var x = 5
}
console.log(x) // 5
```
* ex02
```javascript=
if (true) {
let y = 5
}
console.log(y) // y is not defined
```
* ex03
```javascript=
function allen () {
var x = 5
}
allen()
console.log(x) // x is not defined
```
這邊說明 x 被限制在 Function Scope 中,若裡面找不到變數時則會向外找。
```javascript=
var x = '全域 x'
function fn() {
var x = '區域 x'
console.log(x)
}
console.log(x) // 全域 x
fn() // 區域 x
```
```javascript=
var x = '全域 x'
function fn() {
console.log(x)
}
console.log(x) // 全域 x
fn() // 全域 x
```
* ex04
```javascript=
//函式陳述式
function sum(a, b){
return a+b
}
//函式表達式
const sum = function(a, b) {
return a+b
}
//箭頭函式
const sum = (a, b) => a+b
```
## 小記
:::info
應避免使用 var,改用 let 和 const
const 具備所有 let 的特性,差別在於不能更改值,在明確不會更動資料時使用。
而 function 可以用 ex04 中的的第一及第三種,差別在於第一種會被提升,也就是可以在定義之前調用;
而第二種幾乎可以用第三種取代,第三種又有綁定 this 的好處。
:::
## 參考
[ES6 更嚴謹安全的 let 和 const](https://something-about-js-book.onejar99.com/day08)
[函式與作用域](https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part3/function_scope.html)
[JavaScript 變數宣告與作用域](https://kuro.tw/posts/2015/07/08/note-javascript-variables-declared-with-the-scope-scope/)