iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
Modern Web

JavaScript 基礎修練系列 第 3

[Day03] JavaScript - 變數宣告 var / let / const

此篇再延續上篇,詳細紀錄一下三種宣告方式的不同。
在ES6之前只有var的宣告方式;在ES6之後,即新增了let & const兩種方式:

1.  var - 宣告一個可隨意更改內容的變數 - 函式作用域 (function-level scope)

      ⇒ 只有在「函式」裡可以看得到,特性相當於全域變數

  • 不會受限在區域(block scope)內,可能會汙染全域變數。不管哪個作用域(Scope)都可以存取,可以重複宣告。(若沒有放在函式裡宣告,區域變數會覆蓋全域變數)

    範例如下:

    var a = 5;
    if (true) {
        var a = 10;    //區域變數覆蓋全域變數!!
        console.log(a);  //結果為10
    }
    console.log(a);  //結果為10   
    
  • 再看以下範例,若在一個 函式 內使用 var 宣告變數時,那這個變數就變成了一個區域變數,只有在函式內才看得到。

    var a = 5
    function MyFunction() {
      if (true) {
        var a = 10;
      }
      console.log(a); // 結果為10
    }
    
    MyFunction();
    console.log(a); // 結果為5
    

2.  let - 宣告一個可隨意更改內容的區域變數-區塊作用域 (block-level scope)

      ⇒ 只有在「區塊」裡面才看得到,即只有在 {}花括號 裡的才是它的作用域範圍。

  • 所宣告的變項只有在區域內(block scope)有效,不會產生全域變數,也就是 { } 包住的區域,一但離開 { } 範圍,這個變數就不會被存取到,也無法在同一層 Block 重複宣告變數。

    var b = 6;
    if (true) {
        let b = 20;
        console.log(b);  //出現20
    }
    console.log(b);  //出現6 即為{}外的變數=6
    
    • 無法在同一層 Block 重複宣告變數:

      let a = 6;
      let a = 20;
      console.log(a);
      //出現錯誤:Identifier 'a' has already been declared**
      
    • 但是如果 let 宣告的變數在 不同層的Block ,就不會報錯:

      let a = 6;
      
      if (true) {
      	let a = 20;
      	console.log(a);  //出現20
      }
      console.log(a);  //出現6
      

3.  const - 宣告一個只可讀取的不可變常數-區塊作用域 (block-level scope)

          ⇒ 只有在「區塊」裡面才看得到,即只有在 {}花括號 裡的才是它的作用域範圍。

  • 宣告後不能更改值,否則會報錯

    const a = 123;
    a = 456;  // TypeError: Assignment to constant variable.
    
  • 一宣告時就必定要指定給值,否則會報錯

    const b ;  
    b = 456;   //SyntaxError: Missing initializer in const declaration
    

宣告&不宣告的差異

  • 只要無宣告變數直接賦值就會被視為 全域變數
    (寫在全域環境的 var、let、const 變數同樣可以視為全域變數)

  • 另一點差異是 能不能透過 delet 操作刪除變數 ,先來看下面程式碼:

//未宣告
a = 6;
delete a;   //true
console.log(a);    //a is not defined

//宣告
var b = 10;
delete b;   //false
console.log(b);    //10;

從以上範例可以發現,有使用var宣告的b是不可被刪除的,而未宣告的a可以被刪除。

這是因為如果沒有經過var宣告的變數「會被當作物件屬性」的方式新增,因此才會強烈建議變數一定要宣告,否則可輕易被刪除的變數是很容易出現出問題的。

我們可以透過Object.getOwnPropertyDescriptor來獲取全域屬性: (可參考MDN)

//未宣告
a = 6;
Object.getOwnPropertyDescriptor(window, 'a')
//{value: 6, writable: true, enumerable: true, configurable: true}

//宣告
var b = 10;
Object.getOwnPropertyDescriptor(window, 'b')    
//{value: 10, writable: true, enumerable: true, configurable: false}

由上方a, b 變數的屬性可發現,兩者的配置性configurable有所不同。而configurable為false的代表此物件屬性無法被刪除,configurable為true的則反之。

 因此,經過var宣告的變數是不能被delete的。

 
 
 

參考來源:
https://hsiangfeng.github.io/javascript/20200425/539985371/
https://ithelp.ithome.com.tw/articles/10191549
https://tw.alphacamp.co/blog/javascript-var-let-const


上一篇
[Day02] JavaScript - ES6 概要&語法
下一篇
[Day04] JavaScript - ES6 模板字符串 (Template Literal)
系列文
JavaScript 基礎修練30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言