前言
介紹 Let、Const 的實戰案例
Let 實戰
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log('這執行第' + i + '次');
}, 10);
}
console.log(i);
上面這段程式碼中重要的事情是,setTimeout 會延遲執行現在的 i 是多少,
並且在最外面會印出執行完 for 迴圈之後的 i 是多少。
上一篇文章有講到,因為這邊是用 var 進行變數的宣告,所以最外面的 console.log(i); 是有辦法抓的到 i 的值。
現在又有一個問題來了,因為 setTimeout 是非同步執行的,現在的結果會是我們預期的 0~9,還是都是一樣的 10 呢?
結果是,第一個呈現的是 10,因為 setTimeout 是非同步執行的,所以會在所有的 code 都執行完了以後,才執行。
但為什麼預期的 0~9,會是一樣的 10 呢?
主要原因就是因為 i 是全域變數,而 setTimeout 是非同步執行的,當全部的 code 都執行完以後,才進入事件佇列中進行取
值的動作,這個時候取到的不是for迴圈裡面的 i ,而是全域變數已經被 + 到 10 的 i,所以一直都是顯示10。
而且就算我們把 setTimeout 的時間改成 0,結果也還是一樣的

那麼如果現在是 let 進行宣告變數的話,就可以改善這個問題
for (let i = 0; i < 10; i++) {
setTimeout(function () {
console.log('這執行第' + i + '次');
}, 0);
}
// console.log(i);
只是要記得把最後面的 console.log(i); 給拿掉,因為在 Block 之外的話就取不到裡面的 i 會報錯
const 實戰
var person = {
name: '小明',
money: 500
};
person.name = '杰倫';
以前我們宣告物件的方式都是用這樣的方法進行宣告,並利用 person.name = '杰倫'; 的方式進行物件屬性值的調整。
如果現在換成 const 的話,也是完全沒有問題的。
但 const 宣告的變數是不能做更動的嗎?
沒錯!但是這裡的變數是物件,物件傳參考的特性,所以是不能改變物件參考的位置,但針對物件中的屬性對應的值進行修改是
沒有問題的
如上圖,所以直接改變 person 這個物件的參考位置,也就是重新給予另一個物件的話,就不行!
再來我們把宣告變數改成 var ,並且 freeze (凍結) 該物件,所以理所當然我們沒辦法改動裡面的屬性的值
var person = {
name: '小明',
money: 500
};
person.name = '杰倫';
Object.freeze(person);
person.money = 1000;
這時候,再把這個物件改變成其他物件 (變換物件傳參考的指向)
var person = {
name: '小明',
money: 500
};
person.name = '杰倫';
Object.freeze(person);
person.money = 1000;
person = {};
你會發現 person 的位置被改掉了,如同之前介紹的 freeze 針對的是整個物件的所有屬性,但不包含物件的參考指向,
所以要解決這個問題,只要使用 const 進行變數的宣告就可以。
這樣的話,它就報錯提醒你不可以這樣重新改變 person 這個變數對於物件的指向