iT邦幫忙

2023 iThome 鐵人賽

DAY 14
2
Modern Web

GPT 救救我!菜雞小海獺的前端成長之旅系列 第 14

D14 - JS - 基礎 - 變數與宣告、暫時死區(TDZ)

  • 分享至 

  • xImage
  •  

變數(Variables)

是儲存資料用的容器。容器內可以放字串(String)、數值(Number)、布林值(Boolean)、陣列(Array)或是物件(Object)。

首先要為變數命名並宣告,這樣之後才能呼叫它。變數的命名最好是有意義、短、好發音、(以形容詞搭配的)名詞,而不是隨意取 aaapplecat 這類讓人一頭霧水的無意義名稱。這坑開了,以後苦的是自己XD

常見命名方式

https://ithelp.ithome.com.tw/upload/images/20230915/20161801U9ZS2oQDZx.png
Fig. x. 小駝峰,wiki,駝峰式大小寫 - 維基百科

https://ithelp.ithome.com.tw/upload/images/20230915/20161801taCx2FE7tV.png
Fig. x. 大駝峰,wiki,駝峰式大小寫 - 維基百科

  • 駝峰式(Camel case)

    • 大駝峰(upper camel case)/Pascal Case:每個單字的首字母都是大寫。

      • 例:AnOtter
    • 小駝峰(lower camel case):只有第一個單字的首字母是小寫,其他單字的首字母都是大寫

      • 例:anOtter
  • Snake Case

    • 跟小駝峰一樣,只是單字間以底線 _ 連接
    • 例:an_Otter
  • Kebab Case

    • 跟小駝峰一樣,只是單字間以減號 - 連接
    • 例:an-Otter
    • 修正:JS 不吃此格式,但 HTML 吃
  • Screaming Case

    • 跟 Snake Case 很像,只是每個字母都是大寫
    • 常用在常數的命名
    • 例:AN_OTTER

宣告方式:

var

  • 作用範圍:全域。謎(?)
  • 可以重複宣告,後面的會蓋掉前面的
  • 會有提升(於瀏覽器)與污染的狀況

例:借用 mdn 的例子並略做修改

var x = 1;

console.log("init",x, y); // "init" 1 undefined

if (x === 1) {
  var x = 2;
  var y = 3;

  console.log("inside",x, y); // "inside" 2 3
}

console.log("outside",x, y); // "outside" 2 3

說明:

在 if 內的 var 影響到 if 外的 var,導致 console.log x 的結果永久性的變成 2。
原本外層沒有宣告 y,結果應該要是 not defined,但卻拿到 undefined。
原本好好的,結果宣告的值被汙染,整個亂套拉RR

於是 var 就慢慢的被新出的 let 淹沒惹。(但青菜蘿蔔各有所好就是了)

補充:函式內的 var

function fn1(){
  console.log(a);
  var a=1;
};

fn1(); // undefined

function fn2(){
  var a;
    console.log(a);
  var a=1;
};

fn2(); // undefined

說明:

明明在 fn1 內的順序是先 console.log 再宣告 a,結果執行 fn1 卻出現 undefined?其實 fn1、fn2 兩個函式是一樣的,只是被 var 宣告的變數偷跑,把自己提升(Hoisting)到函式內的最前面了。


let

  • 作用範圍:只作用在當前區域
  • 不可重複宣告,但可重新賦值

把 var 的範例拿來用,只是把 var 改成 let,再修改幾行

let x = 1;

console.log("init", x); // "init" 1

if (x === 1) {
  let x = 2;
  let y = 3;

  console.log("inside", x, y); // "inside" 2 3
}

// let x = 3; // 重複宣告就壞給你看 O_<
x = 3; // 重新賦值

console.log("outside", x); // "outside" 3

逆侃侃,是不是舒服多了?各自作用域劃分的清清楚楚,不用擔心變數被亂改(汙染)了。


const

  • 作用範圍:只作用在當前區域
  • 不可重複宣告,也不可重新賦值
  • 通常用在常數(固定不變的值)上

沿用剛剛的範例,小小修改

console.clear();

const x = 1;

console.log("init", x); // "init" 1

if (x === 1) {
  const x = 2;
  const y = 3;

  console.log("inside", x, y); // "inside" 2 3
}

x = 3; // 到這邊就壞惹

console.log("outside", x); // 所以後面就死掉了

說明:
最外層的 x 跟 if 內的 x 是不同人(作用域各自獨立)。但要重新賦值就又壞惹。

補充:暫時死區(Temporal dead zone)

由於程式的讀取是一行行、由上至下的,所以今天宣告的位置放錯了,讀取就會出問題,最後 code 就掛了。因為對瀏覽器來說,你要它找出變數 x,但以讀取的順序來說,這個變數根本(還)沒宣告、找不到,它不知道要怎麼辦 (只好噴錯)

console.log("init", x); // Uncaught ReferenceError: Cannot access 'x' before initialization

const x = 1;

喔耶寫完開心!


參考資料

  • 駝峰式大小寫 - 維基百科,自由的百科全書,https://zh.wikipedia.org/zh-tw/%E9%A7%9D%E5%B3%B0%E5%BC%8F%E5%A4%A7%E5%B0%8F%E5%AF%AB#
  • 基礎但不簡單: 變數命名規則 | by LSZ | 程式愛好者 | Medium,https://medium.com/%E7%A8%8B%E5%BC%8F%E6%84%9B%E5%A5%BD%E8%80%85/%E8%AE%8A%E6%95%B8%E5%91%BD%E5%90%8D-f53cd1115076
  • 一次說清楚 JavaScript 中宣告的各種提升行為(var、function、let/const) | by realdennis | Medium,https://realdennis.medium.com/%E4%B8%80%E6%AC%A1%E8%AA%AA%E6%B8%85%E6%A5%9A-javascript-%E4%B8%AD%E5%AE%A3%E5%91%8A%E7%9A%84%E5%90%84%E7%A8%AE%E6%8F%90%E5%8D%87%E8%A1%8C%E7%82%BA-var-function-let-const-dd9175d063f0
  • let - JavaScript | MDN,https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/let
  • const - JavaScript | MDN,https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/const

上一篇
D13 - JS - 基礎 - 基礎概念與 API 簡介
下一篇
D15 - JS - 基礎 - 資料型別、運算子、陳述式與表達式定義
系列文
GPT 救救我!菜雞小海獺的前端成長之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言