首頁 > web前端 > js教程 > JS中函數表達式 VS 函數聲明,聊聊它們的不同點

JS中函數表達式 VS 函數聲明,聊聊它們的不同點

青灯夜游
發布: 2021-07-02 09:33:47
轉載
2274 人瀏覽過

在JavaScript中,函數宣告和函數表達式都是使用function關鍵字來建立函數的,是不是覺得它們很像,很容易混淆。以下這篇文章就來帶大家分析一下函數表達式和函數聲明,介紹一下函數表達式和函數宣告的差別。

JS中函數表達式 VS 函數聲明,聊聊它們的不同點

在 JavaScript 中,function關鍵字可以完成一個簡單的工作:建立一個函數。但是,使用關鍵字定義函數的方式可以建立具有不同屬性的函數。

在本文中,我們來看一下,如何使用function關鍵字來定義函數宣告和函數表達式,以及這兩個函數之間的差異又是什麼。

1.函數表達式vs函數宣告

函數宣告和函數表達式是使用 function 關鍵字建立函數的2種方法。

舉個例子來說明差異,我們建立兩個版本的sums 函數:

function sumA(a, b) {
  return a + b;
}

(function sumB(a, b) {
  return a + b;
});

sumA(1, 2); // ???
sumB(1, 2); // ???
登入後複製

動手試試:https://jsfiddle.net/dmitri_pavlutin/8b46yokr/2/

一般情況,像往常一樣定義函數(sumA函數)。在另一種情況下,函數被放置在一對括號中(sumB函數)。

如果呼叫 sumA(1,2)sumB(1,2) 會發生什麼事?

如預期的那樣,sumA(1, 2) 傳回 3。但是,呼叫sumB(1, 2)會引發例外:Uncaught ReferenceError: sumB is not defined

原因是sumA是使用函數宣告建立的,該函數宣告在目前作用域中建立函數變數(具有與函數名稱相同的名稱)。但是sumB是使用函數表達式建立的(將其包裝在括號中),該函數表達式不會在目前作用域內建立函數變數。

如果你想存取使用函數表達式建立的函數,那麼將函數物件儲存到一個變數中:

// Works!
const sum = (function sumB(a, b) {
  return a + b;
});

sum(1, 2); // => 3
登入後複製

如果語句以`function`關鍵字開頭,則為函數聲明,否則為函數表達式。

// 函数声明:以`function`关键字开头
function sumA(a, b) {
  return a + b;
}

// 函数表达式:不以`function`关键字开头
const mySum = (function sumB(a, b) {
  return a + b;
});

// 函数表达式:不以`function`关键字开头
[1, 2, 3].reduce(function sum3(acc, number) { 
  return acc + number 
});
登入後複製

從更高的角度來看,函數宣告對於建立獨立函數很有用,但是函數表達式可以用作回呼。

現在,我們更深入地研究函數宣告和函數表達式的行為。

2.函數宣告

在前面的範例中已經看到的,sumA是一個函數宣告:

// Function declaration
function sumA(a, b) {
  return a + b;
}

sumA(4, 5); // => 9
登入後複製

當一個語句包含function關鍵字,後面跟著函數名稱,一對帶參數的括號(param1, param2, paramN)以及包圍在一對花括號{} 中的函數主體時,就會發生函數宣告。

函數宣告會建立一個函數變數:一個與函數名稱同名的變數(例如,上一個範例中的sumA)。在目前作用域中(在函數宣告之前和之後),甚至在函數作用域本身內,都可以存取該函數變數。

函數變數通常用於呼叫函數或將函數物件傳遞給其他函數(傳遞給高階函數)。

例如,寫一個函數sumArray(array),以遞歸方式累積一個陣列的項(該陣列可以包含數字或其他陣列):

sumArray([10, [1, [5]]]); // => 16

function sumArray(array) {
  let sum = 0;
  for (const item of array) {
    sum += Array.isArray(item) ? sumArray(item) : item;
  }
  return sum;
}

sumArray([1, [4, 6]]); // => 11
登入後複製

#動手試試:https://jsfiddle.net/dmitri_pavlutin/n7wcryuo/

function sumArray(array) { ... }# 是函數宣告。

包含函數物件的函數變數sumArray在目前作用域中可用:sumArray([10, [1, [5]]])之前和sumArray([1, [4, 6]])之後,函數聲明, 以及函數本身的作用域sumArray([1, [4, 6]])(允許遞歸呼叫) 。

由於提升,函數變數在函數宣告之前可用。

2.1 函數宣告的注意事項

函數宣告語法的作用是建立獨立函數。函數宣告應在全域作用域內,或直接在其他函數的作用域內:

// Good!
function myFunc1(param1, param2) {
  return param1 + param2;
}

function bigFunction(param) {
  // Good!
  function myFunc2(param1, param2) {
    return param1 + param2;
  }

  const result = myFunc2(1, 3);
  return result + param;
}
登入後複製

基於相同的原因,不建議在條件(if)和迴圈(whilefor)中使用函數宣告:

// Bad!
if (myCondition) {
  function myFunction(a, b) {
    return a * b;
  }
} else {
  function myFunction(a, b) {
    return a + b;
  }
}

myFunction(2, 3);
登入後複製

使用函數表達式更好地執行有條件地建立函數。

3.函數表達式

function關鍵字在表達式內部建立函數(有或沒有名稱)時,將出現函數表達式。

以下是使用表達式建立的函數的範例:

// Function expressions

const sum = (function sumB(a, b) {
  return a + b;
});

const myObject = {
  myMethod: function() {
    return 42;
  }
};

const numbers = [4, 1, 6];
numbers.forEach(function callback(number) {
  console.log(number);
  // logs 4
  // logs 1
  // logs 1
});
登入後複製

在函數表達式中建立了兩個函數:

  • 如果表達式中的函數沒有名稱,例如function(){return 42},那是匿名函數表達式
  • 如果函數有名稱,例如上一個範例中的sumB和回調,那麼這是一個命名函數表達式

3.1 函數表達式的注意事項

函數表達式適合作為條件創建的回調或函數:

// Functions created conditionally
let callback;
if (true) {
  callback = function() { return 42 };
} else {
  callback = function() { return 3.14 };
}

// Functions used as callbacks
[1, 2, 3].map(function increment(number) {
  return number + 1;
}); // => [2, 3, 4]
登入後複製

如果已建立命名函數表達式,請注意,該函數變數僅在建立的函數作用域內可用:

const numbers = [4];
numbers.forEach(function callback(number) {
  console.log(callback); // logs function() { ... }
});

console.log(callback); // ReferenceError: callback is not defined
登入後複製

试一试:https://jsfiddle.net/dmitri_pavlutin/sujwmp10/2/

callback是一个命名的函数表达式,因此callback函数变量仅在callback()函数使用域可用,而在外部则不可用。

但是,如果将函数对象存储到常规变量中,则可以在函数作用域内外从该变量访问函数对象:

const callback = function(number) {
  console.log(callback); // logs function() { ... }
};

const numbers = [4];
numbers.forEach(callback);
console.log(callback); // logs function() { ... }
登入後複製

试一试:https://jsfiddle.net/dmitri_pavlutin/1btmrcu2/1/

4. 总结

根据使用function关键字创建函数的方式,可以通过两种方法来创建函数:函数声明和函数表达式。

留个问题: function sum(a, b) { return a + b } + 1 是函数声明还是函数表达式,可以在留言中说出你的答案。

英文文章地址:https://dmitripavlutin.com/javascript-function-expressions-and-declarations/

作者:Dmitri Pavlutin

更多编程相关知识,请访问:编程视频!!

以上是JS中函數表達式 VS 函數聲明,聊聊它們的不同點的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:segmentfault.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板