首頁 > web前端 > js教程 > 主體

JavaScript中函數表達式與函數宣告及函數宣告與函數表達式的不同_javascript技巧

WBOY
發布: 2016-05-16 15:32:11
原創
1030 人瀏覽過

函數表達式與函數宣告

在ECMAScript中,創建函數的最常用的兩個方法是函數表達式和函數聲明,兩者期間的區別是有點暈,因為ECMA規範只明確了一點:函數聲明必須帶有標示符(Identifier )(就是大家常說的函數名稱),而函數表達式可以省略這個標示符:

  函數宣告:

  function 函數名稱 (參數:可選){ 函數體 }

  函數表達式:

  function 函數名稱(可選)(參數:可選){ 函數體 }

所以,可以看出,如果不宣告函數名稱,它肯定是表達式,可如果聲明了函數名稱的話,如何判斷是函數宣告還是函數表達式呢? ECMAScript是透過上下文來區分的,如果function foo(){}是作為賦值表達式的一部分的話,那它就是一個函數表達式,如果function foo(){}被包含在一個函數體內,或者位於程式的最頂端的話,那它就是一個函數宣告。

 function foo(){} // 声明,因为它是程序的一部分
 var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分
 new function bar(){}; // 表达式,因为它是new表达式
 (function(){
  function bar(){} // 声明,因为它是函数体的一部分
 })();
登入後複製

還有一個函數表達式不太常見,就是被括號括住的(function foo(){}),他是表達式的原因是因為括號()是一個分組運算符,它的內部只能包含表達式,我們來看幾個例子:

  function foo(){} // 函數宣告
  (function foo(){}); // 函數式:包含在分組運算子內

命名函數表達式

提到命名函數表達式,理所當然,就是它得有名字,前面的例子var bar = function foo(){};就是一個有效的命名函數表達式,但有一點要記住:這個名字只在新定義的函數作用域內有效,因為規範規定了標示符不能在外圍的作用域內有效:

 var f = function foo(){
  return typeof foo; // foo是在内部作用域内有效
 };
 // foo在外部用于是不可见的
 console.log(typeof foo); // "undefined"
 console.log(f()); // "function"
var f = function foo(){
return foo; // foo是在内部作用域内有效
};
// foo在外部用于是不可见的
console.log(typeof foo); // "undefined"
console.log( f()==f); // "function"
console.log(f.name);//foo
登入後複製

既然,這麼要求,那命名函數表達式到底有啥用啊?為啥要取名?

正如我們開頭所說:給它一個名字就是可以讓調試過程更方便,因為在調試的時候,如果在調用棧中的每個項目都有自己的名字來描述,那麼調試過程就太爽了,感受不一樣嘛。

ps:JS中函數宣告與函數表達式的不同

Js中的函數宣告是指下面的形式:

function functionName(){ 
} 
登入後複製

這樣的方式來宣告一個函數,而函數表達式則是類似表達式那樣來宣告一個函數,如:

     var functionName = function(){ 
}
登入後複製

可能很多朋友在看到這兩一種寫法時會產生疑惑,這兩種寫法差不多,在應用中貌似也都是可行的,那他們有什麼差別呢?

 事實上,js的解析器對函數宣告與函數表達式並不是一視同仁地對待的。對於函數聲明,js解析器會優先讀取,確保在所有程式碼執行之前聲明已經被解析,而函數表達式,如同定義其它基本類型的變數一樣,只在執行到某一句時也會對其進行解析,所以在實際中,它們還是會有差異的,具體表現在,當使用函數聲明的形式來定義函數時,可將調用語句寫在函數聲明之前,而後者,這樣做的話會報錯。

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!