0%

JS核心-(59)-ES6 章節:Let 及 Const-Let、Const 實戰運用技巧

前言

介紹 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 ,而是全域變數已經被 +10i,所以一直都是顯示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 這個變數對於物件的指向