今天來看Function Statement
(函式陳述句)與Function Expression
(函式表達式、表示式)
等等...Statement
與Expression
又是什麼東西呢?
Statement
程式碼的單位,這段程式碼不會產生一個值
Expression
程式碼的單位,這段程式碼最終會產生(回傳)一個值,而這個值不一定會被開發者賦予變數。
看看以下程式碼
我們先宣告一個變數a,然後直接在瀏覽器console做後續動作
a = 3
,瀏覽器console回傳3,這代表這段程式碼是Expression
10 + 5
,瀏覽器console回傳15,它也是Expression
a === 3
,回傳true(成立),它也是Expression
a
,瀏覽器console也回傳一個物件,它也是一個Expression
接著看看以下程式碼
if(a === 3){
console.log(a);
}
if()
的()
,需要布林值true
、false
來決定這個程式判斷會不會成立,故()
裡面會放表示式,但if(){}
這段程式碼本身是陳述句,本身不會回傳值,我們也無法將它賦予、指向給變數。
var app = if(a === 3){
console.log(a);
}
現在拉回來函式,函數的定義也有分為Statement
與Expression
例如:
function cat(){
console.log("貓咪");
}
當電腦在執行轉譯的JS程式碼時,上面這段程式並不會報錯,因為它是Function Statement
函式陳述句,程式碼本身不會回傳值,除非我們呼叫執行使其執行。
而這種先宣告函式定義,等待我們(開發者)呼叫執行的寫法,也稱為Function Declaration
函式宣告,它會在電腦的創造階段它就會被設定進記憶體,發生提升Hoisting
現象。
我們可以這樣寫不會報錯
cat()
function cat(){
console.log("貓咪");
}
呼叫執行cat的cat()
雖然寫在函式定義上面,但電腦在創造階段
就先把函式設定進記憶體,在執行階段呼叫其內容,創造其函式執行環境,關於Hoisting
可以參考第三天的筆記。
由於函式就是物件,cat()
這段程式碼,還可以理解成透過cat去查找在記憶體中的function,找到名子NAME屬性cat的函式物件,接著執行其程式屬性console.log("貓咪");
,關於這部分,可以參考昨天筆記。
那Function Expression
函式表示式呢?
var dog = function(){
console.log("狗");
}
dog();
當程式執行到=
運算子右邊的程式碼,才建立這個函式物件,將其指向變數dog,並且它可以當成一個值,所以是Function Expression
表示式。
這裡的函式並沒有名子,也就是說它是一個匿名函式
,var dog = function()
可以理解是將這個逆名函式在記憶體中的位址
傳給變數dog。
而呼叫執行它的程式碼dog()
,則可以理解是透過變數dog有的地址,去呼叫查找在記憶體中的該匿名函式,並執行其程式屬性console.log("狗");
那這樣寫呢?
dog();
var dog = function(){
console.log("狗");
}
變數會在創造階段被設定進記憶體,所以程式碼實際上會像這樣:
var dog
dog();
dog = function(){
console.log("狗");
}
發生了提升現象,呼叫函式時變數dog其實沒有函式,自然報錯dog is not a function
而函式在呼叫執行時,也可以傳參數進去。
接續上面的內容,這裡建一個Function Statement
function log(a){
console.log(a);
}
然後也可以把Function Expression
表示式當成參數傳進去
透過變數
log(dog)
或直接放入匿名函式
log(function(){
console.log("狗");
})
結果
若是想要直接執行這個傳進去的匿名函式,原本的Function Statement可以改成這樣
function log(a){
a();
}
log(function(){
console.log("狗");
})
小結
今天複習了Statement
與Expression
的差別,也複習了函式表示式、函式陳述句,瞭解函式可以當參數傳入其他函式。
明天來看JavaScript的傳值by value
與傳址by reference
。
今天的筆記內容可以參照Udemy課程:JavaScript 全攻略:克服JS 的奇怪部分4-35