函式是可重複使用的模組化陳述式區塊,用於執行一組相關任務,例如根據提供給函式的引數計算及傳回值。和所有非原始值一樣,函式是物件。這些物件是不重複的物件,可供呼叫來執行程式碼、以引數形式傳遞資料,以及return值。
系統會將函式視為「第一個類別」物件,也就是說,即使函式有獨特的行為,可以在與任何其他 JavaScript 物件相同的結構定義中使用這些函式。舉例來說,函式可以指派給變數、做為引數傳遞至其他函式,並由其他函式傳回。
function myFunction() {
console.log( "This is my function." );
};
定義為物件屬性的函式通常稱為「方法」。和使用 var
宣告的變數一樣,在包含函式外建立的函式宣告會以方法的形式加入全域物件中。
函式宣告
函式宣告 (也稱為「函式陳述式」或「函式定義」) 會建立已命名函式,可以在其包含範圍的其他位置叫用。函式宣告由 function
關鍵字後方依序包含 ID、括號括住的參數清單,以及名為「函式主體」的區塊陳述式。您經常會發現結尾不是半形分號的函式宣告。由於函式宣告是陳述式,結尾分號可由 ASI 推論。
function myFunction() {
console.log( "This is my function." );
};
myFunction();
> "This is my function."
由於 JavaScript 早期設計決定的保留,函式宣告必須遵循與使用 var
宣告的變數相同的舊版「提升」行為,意即函式宣告提升至範圍頂端,而在宣告前可以呼叫該範圍,無論該範圍是否受嚴格模式規範:
"use strict";
{
myFunction();
function myFunction() {
console.log( "This is my function." );
};
}
> "This is my function."
在嚴格模式以外,函式宣告會使用 JavaScript 的舊版「範圍限定」行為,表示函式宣告的範圍僅限最接近圍繞的函式:
function myFunction() {
function myNestedFunction() {
console.log( "This is my nested function." );
}
myNestedFunction();
};
myFunction();
> "This is my nested function."
myNestedFunction();
>Uncaught ReferenceError: myNestedFunction is not defined
在嚴格模式中,函式宣告的範圍是以 let
或 const
宣告的變數一樣,限定為最接近的封閉區塊:
"use strict";
{
function myFunction() {
console.log( "This is my function." );
};
}
myFunction();
> Uncaught ReferenceError: myFunction is not defined
函式呼叫
與變數一樣,宣告函式時使用的 ID 作為值的符號名稱。單獨透過 ID 參照函式只會傳回函式物件,系統不會執行其中含有的函式:
function myFunction() {
console.log( "This is my function." );
};
myFunction;
> myFunction() {
console.log( "This is my function." );
}
如要在函式主體中執行程式碼,請在函式名稱後方加上一組相符的括號呼叫 (或「叫用」):
function myFunction() {
console.log( "My function has been executed." );
}
myFunction();
> "My function has been executed."
函式定義中的參數可做為預留位置變數,以供呼叫函式時傳遞至函式主體的值。呼叫函式時,括號中的值皆為「引數」(雖然某些說明文件可能會用「引數」描述引數和參數):
function myFunction( myParameter ) {
console.log( `The value is: ${ myParameter }.` );
};
myFunction( "this string" );
> "The value is: this string."
如果省略預期的引數,產生的參數會包含 undefined
值,因為該參數已宣告給函式主體,但未使用值初始化:
function myFunction( myParameter ) {
console.log( `The value is: ${ myParameter }.` );
};
myFunction();
> "The value is: undefined."
如要設定預設參數值,初始化方式與初始化變數相同:指派運算子 (=
) 後面加上值。如果您之後指定該函式的引數,新值會覆寫預設值:
function myFunction( myParameter = "omitted" ) {
console.log( `The value is: ${ myParameter }.` );
};
myFunction( "this string" );
> "The value is: this string."
myFunction();
> "The value is: omitted."
非箭頭函式的主體也可以存取含有零索引且陣列的 arguments
物件,其中包含任何做為引數傳遞的值,無論函式定義是否指定參數:
function myFunction() {
console.log( arguments );
};
myFunction( 3, true, "My string" );
> Arguments { 0: 3, 1: true, 2: "My string", … }
判斷函式
arguments
物件可讓您建立基本的病毒函式,可接受可變數數量的引數:
function myFunction() {
let result = "";
for (let i = 0; i < arguments.length; i++) {
result += arguments[i] + " - ";
}
console.log( result );
};
myFunction( "My first string", "My second string", "my third string" );\
> "My first string - My second string - my third string - "
不過,現代 JavaScript 開發時很少用到這種變化函式的方法。較常見的做法是使用較新式且可讀取的重設參數語法。系統會建立已初始化的已命名參數,並將其初始化為陣列,其中包含明確指定以外的任何引數:
function myFunction( mySeparator, ...myStrings ) {
console.log( myStrings.join( mySeparator ) );
};
myFunction( " - ", "My first string", "My second string", "my third string" );
> "My first string - My second string - my third string"
與 parameter
繫結不同,休息參數語法可與箭頭函式參數搭配使用:
function myOuterFunction() {
let myInnerArrowFunction = ( ...myParams ) => {
console.log( myParams[ 0 ] );
}
myInnerArrowFunction( true );
};
myOuterFunction( false );
> true
let myArrowFunction = ( ...myParams ) => {
console.log( myParams[ 0 ] );
};
myArrowFunction( true );
> true`
``