---
# System prepended metadata

title: Scope 作用域
tags: [觀念, javascript, 單元筆記]

---

# Scope 作用域

###### tags: `單元筆記` `javascript` `觀念`

## 介紹

區分成 Global 、 Function 、 Block 三種，指的是變數或常數的宣告與語句的可被存取得到的範圍。

* Global : 內層所有地方都可以存取這邊的內容，即全域變數
* Function : var 宣告會被限制在內，不影響外層變數
* Block : 就是以大括號 ( {} ) 劃分出作用的範圍，用 let 宣告會被限制在內，不影響外層變數

大概就像這個樣子的大小範圍

![](https://i.imgur.com/1QhgAgW.png)



## 範例

這邊說明 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/)


