何時使用函式表示式與函式宣告

NLigg發表於2022-03-29

在 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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章