iT邦幫忙

0

#02學習筆記 JavaScript變數宣告

  • 分享至 

  • xImage
  •  

Javascript的宣告方式

在很久很久以前...

其實也沒有多久啦。/images/emoticon/emoticon07.gif

ES6之前宣告的方法都是用var宣告,這也導致很多有趣的事情發生。

所以在ES6之後才導入constlet這兩個宣告的方法。

當今天想要宣告一個常數,會使用const。換而言之要宣告一個變數就會用let

常數跟變數的差別在於:

常數=常數就是記憶體中可以存放資料的地方,但通常不會輕易去改變常數的值。

變數=變數也是記憶體中可以存放資料的地方,而其所存放的值可以被改變。

額外補充

JS當初在設定時比較隨性,所以其實可以不用宣告變數就可以拿來用。

只是如果你沒有宣告,它就會變成一個全域變數而已。

聽起來好像沒什麼大不了的,但通常不建議這麼做,客倌請小心服用啊/images/emoticon/emoticon06.gif
這會導致全域物件的污染,所以千千萬萬不要在還沒宣告變數的狀況下就拿來用!


var跟let的差別

我猜看到這邊一定會想說竟然都已經有var了,為什麼要再產生一個let呢?

既生瑜,何生亮!

因為JS在執行程式的時候會經歷兩個階段:

  1. 建立期:JS會先分配記憶體給宣告的變數及函式,其中函式又會比變數優先被宣告。
    在這段期間又會分為兩個過程,(依照程式碼由上至下的順序)
    註冊名稱 = JS 會宣告變數,但不會賦值給變數。
    初始化 = 因為沒有值的關係,這個變數的值會是undefined。(這邊回應到上一篇文章

  2. 執行期:執行程式碼。
    在執行期也會做兩件事情(依照程式碼由上至下的順序),把宣告變數裡的值指定給變數,執行函式。

過去在使用var宣告的時候會有以下這種狀況

console.log(a)
var a = 3
//  印出 undefined

//  程式碼由上開始往下讀取
//  建立期會跳過 console.log
//  建立期執行註冊名稱  var a  並初始化  var a = undefined
//  回到 console.log ,執行程式碼  undefined => 被印出
//  執行程式碼  a = 3

這種狀況也稱為變數提升(Hoisting),這也是JS才會出現的獨有狀況。

但是後來到ES6後就不會有這種狀況發生了,因為有let跟const的誕生來拯救眾生。

如果上面那段程式碼換成下面這樣:

console.log(a)
let a = 3
//  會噴錯告訴你 ReferenceError: Cannot access 'a' before initialization

TemporalDeadZone暫時死區

差別在於用var 在宣告時變數會變成全域變數,用let 宣告時變數會變成區域變數。
JS 在初始化時會用一個 TDZ (TemporalDeadZone暫時死區) 把變數蓋住,當給予值後才能把蓋子打開。就不會有出現先預設給undfined的問題。
其實都有變數提升的設計,但多了一個TDZ的設計結果就會不一樣,因為變數儲存在記憶體的位置不同。
var沒有TDZ所以在初始化後已經被賦予undefined並儲存進記憶體中。但let跟const都是初始化後被TDZ蓋住並存進TDZ中,直到你賦予它值才可以拿出來。

重複宣告

上面有提到常數跟變數的差別在於值是否可以改變,接下來在做一下討論

const a = 1;
const a = 2;

console.log(a); //SyntaxError: Identifier 'a' has already been declared 
//大概就是說a這個常數已經被宣告。
let b = 1;
let b = 2;

console.log(b);  //SyntaxError: Identifier 'b' has already been declared 
//大概就是說b這個變數已經被宣告。

修但幾勒,上面不是說變數的值可以更改嗎?你這個渣男是不是在欺騙我的感情啊!/images/emoticon/emoticon27.gif

其實如果要修改這個值要用別的方法啦!我才不是什麼愛情的騙子。來示範一下

let b = 1;

b = 2;

console.log(b);  //印出2 
//這樣就可以更改b這個變數的值

這幾天會在整理並在下一篇紀錄Scope chain


參考文獻

網頁前後端寶石庫-礦坑補完計畫系列 第 11 篇 Day 11 JavaScript var vs let (1)


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
alien663
iT邦研究生 5 級 ‧ 2023-05-25 17:13:12

const的內容是不能改變的沒錯,不過如果存的是object,那不能改變的就會變成object的記憶體位置,而不是實際的結構了。

例如

const test = [0, 1, 2, 3]
test.push(4)
console.log(test)
test = ['A', 'B']

你會看到test的結果多了 4,但是指定test為['A', 'B']會失敗。
原因是const test時,其實是在記憶體裡面作了以下事情:

  1. 在記憶體位置(假設為0x00)宣告一個const,名字叫做test,並且記錄test的資料在0x01
  2. 在0x01中,紀錄資料[0, 1, 2, 3]

在以上例子中,真正不能修改的,是0x00這個位置中的值(0x01);但是在0x01這個位置裡面的資料是可以修改的。
因此test = ['A', 'B']這行,會因為重新指定另一個0x02塞到0x00裡面,會報錯誤。

位置 資料
0x00 0x01 (這是個const)
0x01 [0, 1, 2, 3]
0x02 ['A', 'B'] (假設會這樣指定)

不過還是建議const的資料不要隨便修改,需要變動的資料就用let宣告。

Eazy iT邦新手 4 級 ‧ 2023-05-25 17:33:51 檢舉

很棒耶~
感謝大大的補充!

我要留言

立即登入留言