iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0
Modern Web

Node.js 非專業解說系列 第 26

DAY26: 塊作用域

DAY25: 作用域三種類的種類介紹了Nodejs作用域種類,裡面要提到了ES5的作用域,但其實現在的Nodejs有ES6的支持了。

因為在ECMAScript在2009年發布ES5後就沒有後續動作了,
但隨著Web與互聯網愈發進步,ES5存在的缺陷還真不少,
像是,大部分無法支持模塊化、沒有局部作用域等等的問題存在,
所以ES5似乎撐不起在Web界的重責大任了。

在2015年ES6出來問世了,其中它改善了許多在ES5存在的隱患,
在模塊化與作用域這個領域技術更是大大提升,
讓JavaScript有更強大的支撐力。

在每個程式語言都有塊作用域的概念存在,像是以C來說,
if判斷語句或for迴圈等語句都是獨立的塊作用域,會用 { }來定義。
像是

//塊作用域(變量var)
if(true){
    var nicole="Hello Nicole!!";
    var pocky= 2000;
    console.log(nicole);
    console.log(pocky);
}
console.log(nicole); 
console.log(pocky);

執行結果:

https://ithelp.ithome.com.tw/upload/images/20211008/20140244Klxyqdz7ns.png

在if判斷語句中定義關鍵字為var 的nicole與pocky,
在外部也可以被提取到,這表不僅表示if語句是塊作用域也是全局作用域

但在ES5時期,不能滿足這樣的寫法,需要用一個閉包來區隔作用域。
(更多關於閉包的參考資料:
https://zh.wikipedia.org/zh-tw/%E9%97%AD%E5%8C%85_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6))

//使用閉包區隔作用域
function Closure()
{
    var nicole="Hello Nicole!!";
    var pocky= 2000;
    if(true)
    {
        (function Oh()
        {
            var nicole="GoodBye!!";
            var pocky= 10;
            console.log(nicole);
            console.log(pocky);
        }());
    }
   console.log(nicole);
   console.log(pocky);
}
Closure();

執行結果:
所以在ES5中需要通過閉包來完成塊作用域,但現在不需要擔心是否要寫這麼冗長的程式碼,
別忘囉~現在已經是ES6的世期了。

變量提升

有時會在糊里糊塗之下,會把程式順序寫反,
這時候可能就會造成錯誤或是找不到定義的變量或模組的情況發生。
那麼像是下面這種情況,或多或少都有發生過吧!

//變量提升
console.log(nicole);
var nicole="Love Myself";

把執行輸出寫在定義變量的前面了,那麼它會出現甚麼情況呢?

https://ithelp.ithome.com.tw/upload/images/20211008/20140244yhOz4YQ1iB.png

會顯示undefined,但為何不是Error呢?畢竟它在還沒宣告變量的時候就執行了!
但實際上這裏存在一個隱藏式的變量提升,nicole變量的宣告是被提在最前面的部分。
實際上跟下面這種寫法是一樣的。

//不是出現Error的真相是
//上面程式碼相當於下面的寫法
var nicole;  //變量的關鍵字先被宣告
console.log(nicole);
nicole"Love Myself";

總結:

變量提升指示提升了變量的宣告,並不會提升變量的值!!!!!!!/images/emoticon/emoticon77.gif


上一篇
DAY25: 作用域三種類
下一篇
DAY27: var、const、let 在作用域上有甚麼不一樣?
系列文
Node.js 非專業解說30

尚未有邦友留言

立即登入留言