JavaScript 變數生存範圍:var, let, const and scope


Posted by Christy on 2021-09-29

本篇為 [JS201] 進階 JavaScript:那些你一直搞不懂的地方筆記之二。

變數生存範圍 Scope

一、在 ES6 以前變數生存範圍 Scope

1. 函式的作用域只存在於函式裡面

function test() {
  var a = 10
  console.log(a)
}

test() // 會輸出 10

// 假設下面再多一行印出 a,則會出現錯誤訊息如下
console.log(a) // ReferenceError: a is not defined

2. 全域變數表示所有人都看得到

var a =20 // global variable
function test() {
  console.log(a)
}

test() // 20
console.log(a) // 20
// 這裡就很明顯,可以看出作用域的概念了
var a =20
function test() {
  var a = 10
  console.log(a) 
}

test() // 10
console.log(a) // 20

a. The difference between var a = 10 vs a = 10

var a =20 // 3. 原來 a 宣告在這裡,那就把 a 的 值改成 10
function test() {
  a = 10 // 2. 這裡並不是宣告 a 喔
  console.log(a)
}

test() // 輸出 10,1. test 函式裡面並沒有宣告 a
console.log(a) // 10

b. 要宣告變數,一定要在前面加 var

function test() {
  a = 10 // 沒有宣告變數,會自動被宣告成 global 變數,造成以後可能會有衝突
  console.log(a)
}

test() // 10
console.log(a) // 10

c. scope chain: 作用域鏈

inner scope => test scope => global scope

var a = 'global'
function test() {
  var a = 'test global a'
  var b = 'test global b'
  console.log(a, b) // test global a test global b
  function inner () {
    var b = 'inner scope b'
    console.log(a, b) // test global a inner scope b
  }
  inner() // 在執行時,找不到 a 會往上找
}

test()
console.log(a) // global

d. global vs 10? 都幾?不要被迷惑了

Change scope and test scope are parallel. Global scope is higher than these two scopes. The most important part is where the variables are declared and the scope layer in between functions and variables.

change scope and test scope 這兩個作用域是平行的,再上一層是 global scope。重點在於變數在哪裡被宣告跟函式的位置在哪裡。

// global scope
var a = 'global'

//  change scope 
function change() {
  var a = 10
  test()
}

// test scope
function test() {
  console.log(a)
}

change() // global
var a = 'global'

// inner => change => global
// 但是 test => global
// 跟在哪呼叫沒有關係,跟函式結構與變數宣告在哪有關

function change() {
  var a = 10
  function inner() {
    var a = 'inner'
    test()
  }
  inner()
}

function test() {
  console.log(a)
}

change() // 還是會輸出 global

小結:

作用域決定了變數的生存範圍,作用域鏈要看程式碼結構,而會輸出的結果要看變數宣告位置。

但是 js 裡面的 this 會根據呼叫的位置改變值,這也是比較難懂的地方。但是 scope chain 不會。

二、let 與 const 的生存範圍

1. ES6 以後,作用域不一樣了

只要有 block {},就會產生一個新的作用域

使用 let, const 宣告變數時,作用域只會存在於最接近的 {} 裡面;但是用 var 宣告變數,會存在整個函式裡。










Related Posts

[Day 04] - Vault dynamic secrets engine - AWS

[Day 04] - Vault dynamic secrets engine - AWS

[JavaScript] JavaScript 入門

[JavaScript] JavaScript 入門

C# 動態生成物件與其他物件綁定

C# 動態生成物件與其他物件綁定


Comments