激情欧美日韩一区二区,浪货撅高贱屁股求主人调教视频,精品无码成人片一区二区98,国产高清av在线播放,色翁荡息又大又硬又粗视频

JavaScript 函數表達式

時(shí)間:2024-06-28 07:22:11 JavaScript 我要投稿

JavaScript 函數表達式

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

  主要特點(diǎn)

  可選的函數名稱(chēng)

  函數名稱(chēng)是函數聲明的必需組成部分,這個(gè)函數名稱(chēng)相當于一個(gè)變量,新定義的函數會(huì )復制給這個(gè)變量,以后函數的調用都需要通過(guò)這個(gè)變量進(jìn)行。而對于函數表達式來(lái)說(shuō),函數的名稱(chēng)是可選的,例如下面的例子:

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

  這個(gè)例子中函數表達式?jīng)]有名稱(chēng),屬于匿名函數表達式。再看下面的例子:

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

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

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

  這個(gè)特點(diǎn)是函數表達式明顯區別于函數聲明的地方。

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

  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; }

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

  不會(huì )影響變量對象

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

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

  使用場(chǎng)景

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

  函數遞歸

  看下面的例子:

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

  這是一個(gè)經(jīng)典的階乘函數,但是這個(gè)例子存在的一個(gè)問(wèn)題是函數名稱(chēng)factorial與函數體緊密耦合在一起,執行下面的語(yǔ)句就會(huì )報錯:

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

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

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

  這樣在此執行anotherFactorial函數就可以得到正確結果了。但是在嚴格模式"strict"下,arguments.callee是不能通過(guò)腳本訪(fǎng)問(wèn)的,這是就可以使用函數表達式來(lái)解決這個(gè)問(wèn)題了,例如:

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

  代碼模塊化

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

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

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

  (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"

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

【JavaScript 函數表達式】相關(guān)文章:

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

淺析jQuery 遍歷函數javascript08-06

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

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

最常用的20個(gè)javascript方法函數09-10

JavaScript日期時(shí)間格式化函數08-29

JavaScript中常見(jiàn)的字符串操作函數及用法07-24

有關(guān)javascript實(shí)現的多個(gè)層切換效果通用函數示例10-07

對javascript的理解08-08

常用的JavaScript模式09-22

激情欧美日韩一区二区,浪货撅高贱屁股求主人调教视频,精品无码成人片一区二区98,国产高清av在线播放,色翁荡息又大又硬又粗视频