函數聲明和函數表達式有什么區別
function命令聲明的代碼區塊,就是一個函數。function命令后面是函數名,函數名后面是一對圓括號,里面是傳入函數的參數。函數體放在大括號里面。
function print(s) {
console.log(s);
}
上面的代碼命名了一個print函數,以后使用print()這種形式,就可以調用相應的代碼。這叫做函數的聲明(Function Declaration)。
除了用function命令聲明函數,還可以采用變量賦值的寫法。
var print = function(s) {
console.log(s);
};
這種寫法將一個匿名函數賦值給變量。這時,這個匿名函數又稱函數表達式(Function Expression),因為賦值語句的等號右側只能放表達式。
區別:函數表達式通過賦值來聲明函數,聲明完畢后要加上分號表示該句結束,在表達式執行完后,函數才存在并可被調用。而函數聲明與執行順序無關。
什么是變量的聲明前置?什么是函數的聲明前置
JavaScript引擎將函數名視同變量名,所以采用function命令聲明函數時,整個函數會像變量聲明一樣,被提升到代碼頭部。所以,下面的代碼不會報錯。
f();
function f() {}
arguments 是什么
由于JavaScript允許函數有不定數目的參數,所以我們需要一種機制,可以在函數體內部讀取所有參數。這就是arguments對象的由來。
arguments對象包含了函數運行時的所有參數,arguments[0]就是第一個參數,arguments[1]就是第二個參數,以此類推。這個對象只有在函數體內部,才可以使用。
var f = function(one) {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
f(1, 2, 3)
// 1
// 2
// 3
函數的"重載"怎樣實現
在 JS 中
沒有重載! 同名函數會覆蓋。 但可以在函數體針對不同的參數調用執行相應的邏輯。
立即執行函數表達式是什么?有什么作用
有時,我們需要在定義函數之后,立即調用該函數。這時,你不能在函數的定義之后加上圓括號,這會產生語法錯誤。
function(){ /* code */ }();
// SyntaxError: Unexpected token (
產生這個錯誤的原因是,function這個關鍵字即可以當作語句,也可以當作表達式。
// 語句
function f() {}
// 表達式
var f = function f() {}
為了避免解析上的歧義,JavaScript引擎規定,如果function關鍵字出現在行首,一律解釋成語句。因此,JavaScript引擎看到行首是function關鍵字之后,認為這一段都是函數的定義,不應該以圓括號結尾,所以就報錯了。
解決方法就是不要讓function出現在行首,讓引擎將其理解成一個表達式。最簡單的處理,就是將其放在一個圓括號里面。
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();
上面兩種寫法都是以圓括號開頭,引擎就會認為后面跟的是一個表示式,而不是函數定義語句,所以就避免了錯誤。這就叫做“立即調用的函數表達式”(Immediately-Invoked Function Expression),簡稱IIFE。
通常情況下,只對匿名函數使用這種“立即執行的函數表達式”。它的目的有兩個:一是不必為函數命名,避免了污染全局變量;二是IIFE內部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量。避免了污染全局變量。