<dfn id="w48us"></dfn><ul id="w48us"></ul>
  • <ul id="w48us"></ul>
  • <del id="w48us"></del>
    <ul id="w48us"></ul>
  • JavaScript 函數表達式

    時間:2024-06-28 07:22:11 JavaScript 我要投稿

    JavaScript 函數表達式

      JavaScript中創建函數主要有兩種方法:函數聲明和函數表達式。這兩種方式都有不同的適用場景。這篇筆記主要關注的是函數表達式的幾大特點以及它的使用場景,下面一一描述。

      主要特點

      可選的函數名稱

      函數名稱是函數聲明的必需組成部分,這個函數名稱相當于一個變量,新定義的函數會復制給這個變量,以后函數的調用都需要通過這個變量進行。而對于函數表達式來說,函數的名稱是可選的,例如下面的例子:

      var sub = function(a1,a2){ return a1-a2; }

      這個例子中函數表達式沒有名稱,屬于匿名函數表達式。再看下面的例子:

      var sub = function f(a1,a2){ return a1-a2; } console.log(f(5,3)); //錯誤調用方式 console.log(sub(5,3)); //正確調用方式

      在這個例子中,函數表達式的名稱為f,這個名稱f實際上變成了函數內部的一個局部變量,并且指代函數對象本身,在函數遞歸的時候有很大用處,后面會詳細講到。

      在執行階段創建(區別于函數聲明)

      這個特點是函數表達式明顯區別于函數聲明的地方。

      解釋器在解析JavaScript代碼時對于這兩種方式并不是一視同仁的。解釋器會首先讀取函數聲明,并使其在執行任何代碼之前可用;而對于函數表達式,則必須等到解釋器執行到它所在的代碼行,才會被真正解析執行。例如:

      console.log(add(1,2)); //"3" console.log(sub(5,3)); //"unexpected identifier",報錯 function add(a1,a2){ return a1+a2; } var sub = function(a1,a2){ return a1-a2; }

      第一條語句完全可以正常執行。對代碼求值時,JavaScript引擎在第一遍就會聲明函數并通過一個名為函數聲明提升的過程將它們放到源代碼樹的頂部。也就是說在執行環境的創建階段(函數被調用但還沒有開始執行)就會對函數聲明進行"hosting"操作。所以,即使聲明函數的代碼在調用它的代碼后面,JavaScript引擎也會把函數聲明提升到頂部。但是如果把函數聲明更改為函數表達式,就會在執行期間報錯。原因在于在執行到函數所在的語句之前,變量sub中并不會包含對函數的引用。也就是說在代碼執行階段,變量sub才會被賦值。除了以上不同,在其它方面函數聲明和函數表達式的語法是等價的。

      不會影響變量對象

      var sub = function f(a1,a2){ console.log(typeof f); //"function" return a1-a2; } console.log(typeof f); //"Uncaught ReferenceError: f is not defined(…)"

      通過上面的例子可以看到,函數名稱f只能在函數對象內部使用,函數表達式的函數名稱并不存在于變量對象中。

      使用場景

      函數表達式的使用場景很多。下面主要描述的是函數遞歸以及代碼模塊化方面的應用。

      函數遞歸

      看下面的例子:

      function factorial(num){ if(num <= 1){ return 1; }else{ return num * factorial(num - 1); } }

      這是一個經典的階乘函數,但是這個例子存在的一個問題是函數名稱factorial與函數體緊密耦合在一起,執行下面的語句就會報錯:

      var anotherFactorial = factorial; factorial = null; console.log(anotherFactorial(5)); //"Uncaught TypeError: factorial is not a function"

      報錯的原因在于在函數體內部會調用factorial函數,而變量factorial對函數的引用已經被解除所以報錯。這種情況的解決方法一般可以使用arguments.callee來解決,arguments.callee始終指向當前的函數,例如:

      function factorial(num){ if(num <= 1){ return 1; }else{ return num * arguments.callee(num - 1); } }

      這樣在此執行anotherFactorial函數就可以得到正確結果了。但是在嚴格模式"strict"下,arguments.callee是不能通過腳本訪問的,這是就可以使用函數表達式來解決這個問題了,例如:

      var factorial = (function f(num){ if(num <= 1){ return 1; }else{ return num * f(num - 1); } }); console.log(factorial(5)); //"120"

      代碼模塊化

      JavaScript中沒有塊級作用域,但我們可以使用函數表達式模塊化JavaScript代碼。模塊化代碼中可以封裝不必讓使用者知道的細節,只暴露給使用者相關接口,同時可以避免對全局環境的污染,例如:

      var person = (function(){ var _name = ""; return{ getName:function(){ return _name; }, setName:function(newname){ _name = newname; } }; }()); person.setName("John"); person.getName(); //"John"

      這個例子中創建了一個匿名函數表達式,這個函數表達式中包含了模塊自身的私有變量和函數;這個函數表達式的執行結果返回一個對象,對象中包含了模塊暴露給使用者的公共接口。代碼模塊化的具體形式還有很多,例如在一些常用的JavaScript庫中通常都會使用類似下面例子的立即執行函數:

      (function(){ var _name = ""; var root = this; var person = { getName: function(){ return _name; }, setName: function(newname){ _name = newname; } }; root.person = person; }.call(this)); person.setName("John"); person.getName(); //"John"

      這種方式直接將包含模塊公共接口的對象作為全局對象的一個屬性,這樣在其它地方直接可以使用全局對象的這個屬性來使用這個模塊了。

    【JavaScript 函數表達式】相關文章:

    JavaScript基于正則表達式數字判斷函數06-14

    淺析jQuery 遍歷函數javascript08-06

    Javascript函數的定義和用法分析08-15

    JavaScript中push(),join() 函數實例詳解09-05

    最常用的20個javascript方法函數09-10

    JavaScript日期時間格式化函數08-29

    JavaScript中常見的字符串操作函數及用法07-24

    有關javascript實現的多個層切換效果通用函數示例10-07

    對javascript的理解08-08

    常用的JavaScript模式09-22

    主站蜘蛛池模板: 四库影院永久四虎精品国产| 亚洲一区精品伊人久久伊人 | 久久精品国产亚洲一区二区| 日本精品少妇一区二区三区| 国产成人无码精品久久久免费| 精品人无码一区二区三区| 精品伦精品一区二区三区视频| 国内精品在线视频| 国产精品综合色区在线观看| 亚洲精品国产精品乱码不99| 免费看污污的网站欧美国产精品不卡在线观看| 欧美日韩在线亚洲国产精品| 97久久综合精品久久久综合| 精品国产一区二区三区无码| 亚洲精品乱码久久久久久自慰| 天天爽夜夜爽夜夜爽精品视频| 国产内地精品毛片视频| 2024最新国产精品一区| 四虎国产精品免费入口| 久久成人精品视频| 久久精品国产亚洲麻豆| 欧美精品免费线视频观看视频| 500av大全导航精品| 99精品人妻无码专区在线视频区 | 久久99精品国产99久久6| 99久久精品九九亚洲精品| 99精品国产成人一区二区| 中文字幕亚洲精品资源网| www夜片内射视频日韩精品成人| 在线观看日韩精品| 99精品国产成人一区二区| 94久久国产乱子伦精品免费| 99久久99久久精品国产片果冻| 91午夜精品亚洲一区二区三区| 成人国产精品一区二区视频| 国内精品久久久久久久涩爱| 国产欧美精品专区一区二区| 精品国产青草久久久久福利| 久夜色精品国产一区二区三区| 亚洲精品网站在线观看不卡无广告| 亚洲一区精品无码|