更新時間:2021-08-12 12:42:15 來源:動力節(jié)點 瀏覽809次
在 JavaScript 中,函數(shù)不是“神奇的語言結構”,而是一種特殊的值。
我們之前使用的語法稱為函數(shù)聲明:
function sayHi() {
alert( "Hello" );
}
還有另一種創(chuàng)建函數(shù)的語法,稱為函數(shù)表達式。
它看起來像這樣:
let sayHi = function() {
alert( "Hello" );
};
在這里,函數(shù)被創(chuàng)建并顯式分配給變量,就像任何其他值一樣。無論函數(shù)如何定義,它都只是存儲在變量中的一個值sayHi。
這些代碼示例的含義是相同的:“創(chuàng)建一個函數(shù)并將其放入變量中sayHi”。
我們甚至可以使用alert以下方法打印出該值:
function sayHi() {
alert( "Hello" );
}
alert( sayHi ); // shows the function code
請注意,最后一行不運行該函數(shù),因為sayHi. 在某些編程語言中,只要提及函數(shù)名稱就會導致其執(zhí)行,但 JavaScript 并非如此。
在 JavaScript 中,函數(shù)是一個值,所以我們可以將它作為一個值來處理。上面的代碼顯示了它的字符串表示,這是源代碼。
當然,一個函數(shù)是一個特殊的值,我們可以像sayHi().
但它仍然是一個價值。所以我們可以像處理其他類型的值一樣使用它。
我們可以將一個函數(shù)復制到另一個變量:
function sayHi() { // (1) create
alert( "Hello" );
}
let func = sayHi; // (2) copy
func(); // Hello // (3) run the copy (it works)!
sayHi(); // Hello // this still works too (why wouldn't it)
以下是上面發(fā)生的詳細情況:
函數(shù)聲明(1)創(chuàng)建函數(shù)并將其放入名為 的變量中sayHi。
Line 將其(2)復制到變量中func。請再次注意:后面沒有括號sayHi。如果有,那么func = sayHi()會寫 調用的結果 sayHi()為func,不函數(shù) sayHi本身。
現(xiàn)在,該函數(shù)可以同時作為sayHi()和調用func()。
請注意,我們也可以sayHi在第一行中使用函數(shù)表達式來聲明:
let sayHi = function() {
alert( "Hello" );
};
let func = sayHi;
// ...
讓我們看一下將函數(shù)作為值傳遞和使用函數(shù)表達式的更多示例。
我們將編寫一個ask(question, yes, no)帶有三個參數(shù)的函數(shù):
question
問題的文本
yes
答案為“是”時運行的函數(shù)
no
如果答案為“否”則運行的函數(shù)
該函數(shù)應詢問question和 ,具體取決于用戶的回答,調用yes()或no():
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "You agreed." );
}
function showCancel() {
alert( "You canceled the execution." );
}
// usage: functions showOk, showCancel are passed as arguments to ask
ask("Do you agree?", showOk, showCancel);
在實踐中,這些功能非常有用。現(xiàn)實生活ask和上面的例子之間的主要區(qū)別在于,現(xiàn)實生活中的函數(shù)使用比簡單的confirm. 在瀏覽器中,這樣的功能通常會繪制一個漂亮的問題窗口。但那是另一個故事了。
參數(shù)showOk和showCancelofask被稱為回調函數(shù)或只是callbacks。
這個想法是我們傳遞一個函數(shù)并期望它在必要時被“回調”。在我們的例子中,showOk成為“是”回答和“否”回答的回調showCancel。
我們可以使用函數(shù)表達式將相同的函數(shù)寫得更短:
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"Do you agree?",
function() { alert("You agreed."); },
function() { alert("You canceled the execution."); }
);
讓我們制定函數(shù)聲明和表達式之間的主要區(qū)別。
語法:如何在代碼中區(qū)分它們。
函數(shù)聲明:在主代碼流中聲明為單獨語句的函數(shù)。
// Function Declaration
function sum(a, b) {
return a + b;
}
函數(shù)表達式:在表達式或另一個語法結構中創(chuàng)建的函數(shù)。這里,函數(shù)是在“賦值表達式”的右側創(chuàng)建的=:
// Function Expression
let sum = function(a, b) {
return a + b;
};
更細微的區(qū)別是JavaScript 引擎何時創(chuàng)建函數(shù)。
函數(shù)表達式在執(zhí)行到達時創(chuàng)建,并且僅從那一刻起可用。
一旦執(zhí)行流程傳遞到賦值的右側let sum = function…——我們開始,函數(shù)就被創(chuàng)建并且可以從現(xiàn)在開始使用(賦值、調用等)。
函數(shù)聲明是不同的。
函數(shù)聲明可以在定義之前被調用。
例如,全局函數(shù)聲明在整個腳本中都是可見的,無論它在哪里。
這是由于內部算法。當 JavaScript 準備運行腳本時,它首先在其中查找全局函數(shù)聲明并創(chuàng)建函數(shù)。我們可以將其視為“初始化階段”。
并且在處理完所有函數(shù)聲明之后,執(zhí)行代碼。所以它可以訪問這些功能。
例如,這有效:
sayHi("John"); // Hello, John
function sayHi(name) {
alert( `Hello, ${name}` );
}
函數(shù)聲明sayHi是在 JavaScript 準備啟動腳本時創(chuàng)建的,并且在腳本中的任何地方都可見。
...如果它是一個函數(shù)表達式,那么它就行不通了:
sayHi("John"); // error!
let sayHi = function(name) { // (*) no magic any more
alert( `Hello, ${name}` );
};
函數(shù)表達式在執(zhí)行到達時創(chuàng)建。那只會發(fā)生在行中(*)。太晚了。
函數(shù)聲明的另一個特點是它們的塊作用域。
在嚴格模式下,當函數(shù)聲明在代碼塊內時,它在該塊內的任何地方都是可見的。但不是在它之外。
例如,假設我們需要welcome()根據(jù)age運行時獲得的變量聲明一個函數(shù)。然后我們計劃稍后使用它。
如果我們使用函數(shù)聲明,它將無法按預期工作:
let age = prompt("What is your age?", 18);
// conditionally declare a function
if (age < 18) {
function welcome() {
alert("Hello!");
}
} else {
function welcome() {
alert("Greetings!");
}
}
// ...use it later
welcome(); // Error: welcome is not defined
這是因為函數(shù)聲明僅在它所在的代碼塊內可見。
這是另一個例子:
let age = 16; // take 16 as an example
if (age < 18) {
welcome(); // \ (runs)
// |
function welcome() { // |
alert("Hello!"); // | Function Declaration is available
} // | everywhere in the block where it's declared
// |
welcome(); // / (runs)
} else {
function welcome() {
alert("Greetings!");
}
}
// Here we're out of curly braces,
// so we can not see Function Declarations made inside of them.
welcome(); // Error: welcome is not defined
我們可以做些什么來使welcome外部可見if?
正確的方法是使用函數(shù)表達式并分配welcome給在外部聲明if并具有適當可見性的變量。
此代碼按預期工作:
let age = prompt("What is your age?", 18);
let welcome;
if (age < 18) {
welcome = function() {
alert("Hello!");
};
} else {
welcome = function() {
alert("Greetings!");
};
}
welcome(); // ok now
或者我們可以使用問號運算符進一步簡化它?:
let age = prompt("What is your age?", 18);
let welcome = (age < 18) ?
function() { alert("Hello!"); } :
function() { alert("Greetings!"); };
welcome(); // ok now
以上就是動力節(jié)點小編介紹的"函數(shù)表達式",希望對大家有幫助,想了解更多可查看Java在線學習。動力節(jié)點在線學習教程,針對沒有任何Java基礎的讀者學習,讓你從入門到精通,主要介紹了一些Java基礎的核心知識,讓同學們更好更方便的學習和了解Java編程,感興趣的同學可以關注一下。