何時使用函式表示式與函式宣告
在 JavaScript 中建立函式有兩種方法:函式表示式和函式宣告。 在本文中,我們將討論何時使用函式表示式與函式宣告,並解釋它們之間的區別。
函式宣告已經使用了很長時間,但函式表示式已經逐漸佔據主導地位。 許多開發人員不確定何時使用其中一種,因此他們最終使用了錯誤的一種。
函式表示式和函式宣告之間有一些關鍵區別。 讓我們仔細看看這些差異,以及何時在程式碼中使用函式表示式與函式宣告。
function funcDeclaration() { return 'A function declaration';}let funcExpression = function () { return 'A function expression';}
什麼是函式宣告?
函式宣告是在您建立函式併為其命名時。 在編寫 function 關鍵字時宣告函式的名稱,然後是函式名稱。 例如:
let myFunction = function() { // do something};
如您所見,函式名稱 (
myFunction
) 是在建立函式時宣告的。
這意味著您可以在定義之前呼叫該函式。
下面是一個函式宣告的例子:
function add (a, b) { return a + b;};
什麼是函式表示式?
函式表示式是在您建立函式並將其分配給變數時。 該函式是匿名的,這意味著它沒有名稱。 例如:
let myFunction = function() { // do something};
如您所見,該函式已分配給
myFunction
變數。
這意味著您必須先定義該函式,然後才能呼叫它。
下面是一個函式表示式的例子:
let add = function (a, b) { return a + b;};
函式表示式和宣告之間的區別
函式表示式和函式宣告之間有幾個關鍵區別:
- 函式宣告被提升,而函式表示式則沒有。 這意味著您可以在定義函式宣告之前呼叫它,但不能使用函式表示式執行此操作。
- 使用函式表示式,您可以在定義函式後立即使用它。 使用函式宣告,您必須等到整個指令碼被解析。
- 函式表示式可以用作另一個函式的引數,但函式宣告不能。
- 函式表示式可以是匿名的,而函式宣告則不能。
瞭解函式表示式中的作用域:JavaScript 提升差異
與
let
語句類似,函式宣告
被提升到
其他程式碼的頂部。
函式表示式沒有被提升。 這允許他們從定義它們的範圍內保留區域性變數的副本。
通常,您可以互換使用函式宣告和函式表示式。 但有時函式表示式會生成更易於理解的程式碼,而不需要臨時函式名。
如何在表示式和宣告之間進行選擇
那麼,什麼時候應該使用函式表示式與函式宣告呢?
答案取決於您的需求。 如果您需要更靈活的函式或未提升的函式,那麼函式表示式是可行的方法。 如果您需要更易讀易懂的函式,請使用函式宣告。
如您所見,這兩種語法是相似的。 最明顯的區別是函式表示式是匿名的,而函式宣告是有名字的。
今天,當你需要做一些函式表示式不能做的事情時,你通常會使用函式宣告。 如果您不需要做任何只能通過函式宣告才能完成的事情,那麼通常最好使用函式表示式。
當您需要建立遞迴函式或需要在定義函式之前呼叫該函式時,請使用函式宣告。 根據經驗,當您不需要做任何這些事情時,使用函式表示式來獲得更簡潔的程式碼。
函式宣告的好處
使用函式宣告有幾個關鍵的好處。
- 它可以使您的程式碼更具可讀性。 如果你有一個很長的函式,給它一個名字可以幫助你跟蹤它在做什麼。
- 函式宣告是提升的 ,這意味著它們在您的程式碼中定義之前就可用。 如果您需要在定義之前使用該函式,這將很有幫助。
函式表示式的好處
函式表示式也有一些好處。
- 它們比函式宣告更靈活。 您可以建立函式表示式並將它們分配給不同的變數,這在您需要在不同的地方使用相同的函式時會很有幫助。
- 函式表示式未提升 ,因此在程式碼中定義它們之前您不能使用它們。 如果您想確保函式僅在定義後使用,這將很有幫助。
何時選擇函式宣告與函式表示式
在大多數情況下,很容易找出最適合您需要的函式定義方法。 這些指南將幫助您在大多數情況下快速做出決定。
在以下情況下使用函式宣告:
- 您需要一個更具可讀性和可理解性的函式(例如一個長函式,或者您需要在不同地方使用的函式)
- 匿名函式不適合您的需求
- 您需要建立一個遞迴函式
- 您需要在定義之前呼叫該函式
在以下情況下使用函式表示式:
- 你需要一個更靈活的功能
- 你需要一個沒有提升的功能
- 該函式只應在定義時使用
- 該函式是匿名的,或者不需要名稱供以後使用
- 您想使用立即呼叫函式表示式 (IIFE) 等技術來控制函式何時執行
- 您想將函式作為引數傳遞給另一個函式
也就是說,在許多情況下,函式表示式的靈活性成為一項強大的資產。
解鎖函式表示式:JavaScript 提升差異
有幾種不同的方式可以使函式表示式變得比函式宣告更有用。
- 閉包
- 其他函式的引數
- 立即呼叫函式表示式 (IIFE)
使用函式表示式建立閉包
當您想在函式執行之前為函式提供引數時,使用閉包。
迴圈通過
NodeList
.
閉包允許您保留其他資訊,例如索引,在函式執行後該資訊不可用的情況下。
function tabsHandler(index) { return function tabClickEvent(evt) { // Do stuff with tab. // The index variable can be accessed from within here. };}let tabs = document.querySelectorAll('.tab'), i;for (i = 0; i < tabs.length; i += 1) { tabs[i].onclick = tabsHandler(i);}
附加的事件處理程式稍後執行(迴圈完成後),因此需要一個閉包來保留
for
迴圈的適當值。
// Bad code, demonstrating why a closure is neededlet i;for (i = 0; i < list.length; i += 1) { document.querySelector('#item' + i).onclick = function doSomething(evt) { // Do something with item i // But, by the time this function executes, the value of i is always list.length }}
doSomething()
通過從
for
迴圈中
提取函式,更容易理解為什麼會出現問題。
// Bad code, demonstrating why a closure is neededlet list = document.querySelectorAll('.item'), i, doSomething = function (evt) { // Do something with item i. // But, by the time this function executes, the value of i is not what it was in the loop. };for (i = 0; i < list.length; i += 1) { item[i].onclick = doSomething;}
這裡的解決方案是將索引作為函式引數傳遞給外部函式,以便它可以將該值傳遞給內部函式。 您通常會看到處理函式用於組織內部返回函式所需的資訊。
// The following is good code, demonstrating the use of a closurelet list = ['item1', 'item2', 'item3'], i, doSomethingHandler = function (itemIndex) { return function doSomething(evt) { // now this doSomething function can retain knowledge of // the index variable via the itemIndex parameter, // along with other variables that may be available too. console.log('Doing something with ' + list[itemIndex]); }; };for (i = 0; i < list.length; i += 1) { list[i].onclick = doSomethingHandler(i);}
瞭解更多關於 閉包及其用法的資訊 。
將函式表示式作為引數傳遞
函式表示式可以直接傳遞給函式,而不必分配給中間臨時變數。
您最常以匿名函式的形式看到它們。 這是一個熟悉的 jQuery 函式表示式示例:
$(document).ready(function () { console.log('An anonymous function');});
在使用諸如
forEach()
.
它們也不必是未命名的匿名函式。 命名函式表示式以幫助表達函式應該做什麼並幫助除錯是一個好主意:
let productIds = ['12356', '13771', '15492'];productIds.forEach(function showProduct(productId) { ...});
立即呼叫函式表示式 (IIFE)
IIFE 有助於防止您的函式和變數影響全域性範圍。
其中的所有屬性都在匿名函式的範圍內。 這是一種常見的設計模式,用於防止您的程式碼在其他地方產生不希望的或不希望的副作用。
它還用作模組模式,在易於維護的部分中包含程式碼塊。 我們將在 Demystifying JavaScript 閉包、回撥和 IIFE 中深入瞭解這些內容。
下面是一個 IIFE 的簡單示例:
(function () { // code in here}());
…當用作模組時,可以為您的程式碼帶來一些易於實現的可維護性。
let myModule = (function () { let privateMethod = function () { console.log('A private method'); }, someMethod = function () { console.log('A public method'); }, anotherMethod = function () { console.log('Another public method'); }; return { someMethod: someMethod, anotherMethod: anotherMethod };}());
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70015022/viewspace-2884809/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 函式宣告與函式表示式有什麼區別?函式
- JavaScript函式宣告和函式表示式區別JavaScript函式
- javascript 的函式宣告與表示式對比JavaScript函式
- Python函式與lambda 表示式(匿名函式)Python函式
- JS 中的函式表示式和函式宣告你混淆了嗎?JS函式
- webgl內建函式--幾何函式與矩陣函式Web函式矩陣
- 課時21:函式:lambda表示式函式
- 06函式宣告函式
- JS函式表示式——函式遞迴、閉包JS函式遞迴
- javascript-函式表示式JavaScript函式
- 函式表示式–遞迴函式遞迴
- JS 命令式 宣告式 函式式 程式設計?JS函式程式設計
- 通過一道面試題來學習原型/原型鏈-函式宣告/函式表示式面試題原型函式
- JavaScript 變數與函式宣告前置JavaScript變數函式
- C++ lambda 表示式與「函式物件」(functor)C++函式物件
- matlab表示函式Matlab函式
- Python中eval函式的表示式如何使用Python函式
- 何時/如何使用 Vue3 render 函式Vue函式
- Lambda表示式入門--函數語言程式設計與函式式介面函數程式設計函式
- kotlin 函式和 Lambda 表示式Kotlin函式
- Kotlin 之高階函式與Lambda表示式與閉包Kotlin函式
- jdk1.8-Lambda函式表示式JDK函式
- 5.函式和lambda表示式函式
- jdk1.8Lambda函式表示式JDK函式
- 初識Lambda表示式(匿名函式)函式
- JavaScript 之有趣的函式(函式宣告、呼叫、預解析、作用域)JavaScript函式
- 瞭解 JavaScript 函數語言程式設計 - 宣告式函式JavaScript函數程式設計函式
- JS變數宣告和函式宣告提升JS變數函式
- webgl內建函式--向量函式與紋理查詢函式Web函式
- Oracle 正規表示式函式-REGEXP_REPLACE 使用例子Oracle函式
- MySQL函式大全(字串函式,數學函式,日期函式,系統級函式,聚合函式)MySql函式字串
- Oracle分析函式與視窗函式Oracle函式
- 建構函式與解構函式函式
- 函式節流與函式防抖函式
- 回撥函式 與 函式閉包函式
- 【Python】python map()函式和lambda表示式Python函式
- 探索MySQL高階語句(數學函式、聚合函式、字串函式、日期時間函式)MySql函式字串
- 函式: 函式是怎麼使用的?函式