• <sub id="h4knl"><ol id="h4knl"></ol></sub>
    <sup id="h4knl"></sup>
      <sub id="h4knl"></sub>

      <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
      1. <strong id="h4knl"></strong>

      2. JavaScript 函數(shù)表達(dá)式

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

        JavaScript 函數(shù)表達(dá)式

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

          主要特點(diǎn)

          可選的函數(shù)名稱

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

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

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

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

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

          在執(zhí)行階段創(chuàng)建(區(qū)別于函數(shù)聲明)

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

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

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

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

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

          使用場景

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

          函數(shù)遞歸

          看下面的例子:

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

          這是一個(gè)經(jīng)典的階乘函數(shù),但是這個(gè)例子存在的一個(gè)問題是函數(shù)名稱factorial與函數(shù)體緊密耦合在一起,執(zhí)行下面的語句就會(huì)報(bào)錯(cuò):

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

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

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

          這樣在此執(zhí)行anotherFactorial函數(shù)就可以得到正確結(jié)果了。但是在嚴(yán)格模式"strict"下,arguments.callee是不能通過腳本訪問的,這是就可以使用函數(shù)表達(dá)式來解決這個(gè)問題了,例如:

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

          代碼模塊化

          JavaScript中沒有塊級作用域,但我們可以使用函數(shù)表達(dá)式模塊化JavaScript代碼。模塊化代碼中可以封裝不必讓使用者知道的細(xì)節(jié),只暴露給使用者相關(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è)匿名函數(shù)表達(dá)式,這個(gè)函數(shù)表達(dá)式中包含了模塊自身的私有變量和函數(shù);這個(gè)函數(shù)表達(dá)式的執(zhí)行結(jié)果返回一個(gè)對象,對象中包含了模塊暴露給使用者的公共接口。代碼模塊化的具體形式還有很多,例如在一些常用的JavaScript庫中通常都會(huì)使用類似下面例子的立即執(zhí)行函數(shù):

          (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è)屬性來使用這個(gè)模塊了。

        《&.doc》
        将本文的Word文档下载到电脑,方便收藏和打印
        推荐度:
        点击下载文档

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

        JavaScript基于正則表達(dá)式數(shù)字判斷函數(shù)06-14

        淺析jQuery 遍歷函數(shù)javascript08-06

        Javascript函數(shù)的定義和用法分析08-15

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

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

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

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

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

        對javascript的理解08-08

        常用的JavaScript模式09-22

        在线咨询
        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码
      3. <sub id="h4knl"><ol id="h4knl"></ol></sub>
        <sup id="h4knl"></sup>
          <sub id="h4knl"></sub>

          <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
          1. <strong id="h4knl"></strong>

          2. 制服丝袜国产中文亚洲 | 亚洲a∨天堂久久 | 香蕉人成年视频在线观看 | 亚洲国产aⅴ精品一区二区久久 | 中文字幕制服综合第一页 | 久久成人免费精品二区 |

            JavaScript 函數(shù)表達(dá)式

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

              主要特點(diǎn)

              可選的函數(shù)名稱

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

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

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

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

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

              在執(zhí)行階段創(chuàng)建(區(qū)別于函數(shù)聲明)

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

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

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

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

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

              使用場景

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

              函數(shù)遞歸

              看下面的例子:

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

              這是一個(gè)經(jīng)典的階乘函數(shù),但是這個(gè)例子存在的一個(gè)問題是函數(shù)名稱factorial與函數(shù)體緊密耦合在一起,執(zhí)行下面的語句就會(huì)報(bào)錯(cuò):

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

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

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

              這樣在此執(zhí)行anotherFactorial函數(shù)就可以得到正確結(jié)果了。但是在嚴(yán)格模式"strict"下,arguments.callee是不能通過腳本訪問的,這是就可以使用函數(shù)表達(dá)式來解決這個(gè)問題了,例如:

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

              代碼模塊化

              JavaScript中沒有塊級作用域,但我們可以使用函數(shù)表達(dá)式模塊化JavaScript代碼。模塊化代碼中可以封裝不必讓使用者知道的細(xì)節(jié),只暴露給使用者相關(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è)匿名函數(shù)表達(dá)式,這個(gè)函數(shù)表達(dá)式中包含了模塊自身的私有變量和函數(shù);這個(gè)函數(shù)表達(dá)式的執(zhí)行結(jié)果返回一個(gè)對象,對象中包含了模塊暴露給使用者的公共接口。代碼模塊化的具體形式還有很多,例如在一些常用的JavaScript庫中通常都會(huì)使用類似下面例子的立即執(zhí)行函數(shù):

              (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è)屬性來使用這個(gè)模塊了。