JavaScript 作用域(Scope)

了解全局作用域,函數作用域和塊級作用域之間的區別。了解哪些變數在哪些地方可用。知道 JavaScript 引擎如何執行變數查詢。

JavaScript基本觀念之一,在JavaScript有兩種類型的作用域。

  • Global Scope (全域)
  • Local Scope (區域)

在函數之外定義的變數是全域變數,每個函式被調用時,會創建一個新的作用域

Global Scope

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var name = 'Stoner';
console.log(name); //-> 'Stoner'

function logName() {
console.log(name);
}

logName(); //-> 'Stoner'

if (true) {
// 'if' 條件語句不會創建一個新的作用域
var name = 'Hammad'; // name 依然在全局作用域中
}

console.log(name); // logs 'Hammad'

Local Scope

1
2
3
4
5
6
7
8
9
10
11
12
13
// Global Scope
function someFunction() {
// Local Scope #1
function someOtherFunction() {
// Local Scope #2
}
}

// Global Scope
function anotherFunction() {
// Local Scope #3
}
// Global Scope

ES6

在ES6中新增了兩個宣告變量 let、const

  • let 宣告了一個塊級作用域的局部變數,它的作用範圍為最接近的塊作用域(如果在所有塊以外就是全局作用域),這將會比 var 的函數作用域更小。
  • const 宣告的是一個只讀的變數,而該變數一旦宣告,變數的值就無法更改。const 宣告的變數不得改變值,也就是說,const 一旦宣告變數,就必須立即初始化,不能留到之後給值。
  1. const 和 let 只在宣告所在的塊級作用域内有效。
  2. 宣告變數後就必須綁定在這區域不再受到外部影響。
  3. 是不可重複宣告變數。
  4. 必須在嚴格模式下才可以使用 const let。
  5. const 和 let 不存在提升(Hoisting)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
console.log(i); // 输出 undefined
console.log(j); // Error
var i = 1;
let j = 1;

if (true) {
// 'if' 條件語句不會創建一個新的作用域

// name 在全局作用域中,因為通過 'var' 關鍵字定義
var name = 'Hammad';
// likes 在局部(本地)作用域中,因為通過 'let' 關鍵字定義
let likes = 'Coding';
// skills 在局部(本地)作用域中,因為通過 'const' 關鍵字定義
const skills = 'JavaScript and PHP';
}

console.log(name); // logs 'Hammad'
console.log(likes); // Uncaught ReferenceError: likes is not defined
console.log(skills); // Uncaught ReferenceError: skills is not defined

更多範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//下面是宣告一個全域變數 a,然後值為 1,所以在後面的匿名函式中可以使用它
var a = 1;
(function(){
console.log(a); //-> 1
})();

//在匿名函式內,又宣告了一個 a,因為作用域的關係,console吃到的 a 是Local Scope的變數
var a = 1;
(function(){
var a = 100;
console.log(a); //-> 100
})();

//匿名函數獨立的 scope 內,不管 var 是放在最前面,或是最後一行,他的變數實體在該 code block 一開始就是新的了
var a = 1;
(function(){
var a;
console.log(a); // undefined
a = 100;
console.log(a); // 100
})();

//排除上面的問題要這樣子做
var a = 1;
(function(_a){
console.log(_a); // 1
var a = 100;
console.log(a); // 100
})(a);


var i = 1;
if (i) {
function temporary() {
var i = 2;
console.log(i); //-> 2
}
temporary();
}
console.log(i); //-> 1

原文

JavaScript 中的作用域(scope)和提升(hoisting)
[筆記] JavaScript 變數宣告與作用域
Understanding Scope in JavaScript
Understanding Scope in JavaScript(中文)

0%