前言
陳述式(Statement)與表達式(Expression)最大的差別在:陳述式不會回傳結果
陳述式與表達式
可以透過 MDN 文件了解 JavaScript 的陳述式 陳述式 與 表達式 有那些
陳述式有
var、let、const、if...else、for…等等
表達式經常會與運算子搭配並回傳結果
陳述式 (Statement)
基本上陳述式是不會回傳結果的,在這邊你應該會覺得很奇怪,剛才不是說表達式通常會搭配運算子並回傳結果嗎?那麼變數宣告的 var a = 1; 有回傳一個 undefined 為什麼不算是一個表達式呢?而且他也有 = 運算子,這樣子不算是表達式嗎?
相信很多人對於「變數宣告」為什麼是一個陳述式感到疑惑,陳述式最簡單的觀念來自「它只會靜靜躺在那邊等你呼叫,最大特徵在於不會回傳任何的結果,但是陳述式必定會先執行過一次」,其主要原因在於它要先確定語法作用域。
因此若在 Chrome 上的 console 輸入 var a = 1; 卻會回傳 undefined 的原因在於變數宣告時,JavaScript 會先執行過一次,因為它要替這個變數準備一個記憶體空間,並將記憶體空間與變數名稱對應,但並不會回傳結果,因此變數宣告才會回傳給你一個 undefined,而在這邊的 undefined 只是告訴你我已經替這個變數宣告準備好了記憶體空間而已。
表達式 (Expression)
表達式又稱之為運算式,也可以稱為表示式,最間單的觀念理解在於它會回傳一個值,例如當你輸入 1+1 它會在底下回傳一個 2,而這就是表達式
> 1+1
< 2
在 MDN 中有說明運算式的幾個特徵
算數: 解析出數字, 例如 3.14159. (通常使用 算術運算子)
字串: 解析出字串, 例如 “Fred” or “234”。 (通常使用 字串運算子)
邏輯: 解析出 True 或 False (通常與 邏輯運算子 相關)
主流運算式: JavaScript 基本的關鍵字及運算式
左側運算式: 左側是指定值的對象
表達式最簡單的便是觀念在於「會回傳一個結果 or 一個值」,因此當我們輸入 hi = 'Bob' 它會回傳一個 'Bob' 這就是表達式
> hi = 'Bob';
< 'Bob'
而表達式的重點觀念在於運算子,因此等號是一個表達式,它會將值賦予到 hi 並回傳結果,因此我們這邊可以回顧一下變數宣告中的 var a = '10'; 為什麼會回傳 undefined,前面有說過變數宣告會回傳 undefined 的原因在於它準備好一個空間給記憶體給變數使用,接下來讓我們看一下其他陳述式通常會發生什麼事情
if(true) {
}
//undefined
function fu() {}
//undefined
for(var i; i< 10;i++) {}
//undefined
你會發現只要是陳述式它就只會回傳 undefined
反之表達式就不同,表達式必定會回傳一個結果一個值
hi = 'Bob';
//'Bob'
1+1;
//2
w = true;
//true
d = function () {}
//f () {}
另外,我們常在開發使用的 setTimeout 以及 setInterval 也是屬於表達式
> setTimeout(function(){}, 10000); // 1000 = 1 秒
< 7
> setInterval(function(){}, 10000);
< 8
此外陳述式與表達式還有一個特徵可以辨別,也就是陳述式無法被變數儲存,因為陳述式不會回傳值的關係
a = if (true) {};
// Uncaught SyntaxError: Unexpected token 'if'
函式陳述式
接下來講另一種的陳述式與表達式,函式在宣告時其實也有分為兩種廣義的宣告方式,第一種就是所謂的函式陳述式
function fu() {
}
基本上函式陳述式在宣告時,並不會回傳結果,而是與前面相同,僅會回傳 undefined,此外上面的函式陳述式又稱之為具名函式陳述式
函式表達式
函式表達式通常會宣告一個變數並搭配等號運算子以及一個函式,而這個就是所謂的函式表達式
var fu = function() {}
而這個宣告函式的方式又稱之為匿名函式表達式,雖然你在 Chrome 中,輸入他一樣會回傳給你一個 undefined,但實際上因為這個函式沒有 name 所以會被回傳儲存在 fu 的變數內,而函式表達式最大的特徵在於他不會受到提升的影響,因此若你在函式表達式之前呼叫,它就會出現錯誤訊息
fu();
var fu = function() {}
//Uncaught TypeError: fu is not a functionat <anonymous>:1:1
block 與物件實字
在 JavaScript 中有一個 block,也就是 {}, block 在 MDN 中也是屬於陳述式,因此可以這樣寫
{
var hi = 'Bob';
}
但是若是改寫成物件實字則是使用「:」來區分屬性與值
{
hi: 'Bob',
}
而這邊兩者最大差異在於物件實字是一個表達式,因此表達式我們可以儲存進變數內中
var a = {
hi: 'Bob',
};
但若是 block 則是不行,因為他是一個陳述式
var b = {
var hi = 'Bob';
}
// Uncaught SyntaxError: Unexpected identifier
結論
只要會回傳結果或是值,那麼就是屬於表達式,若不會那麼就是陳述式