1. <rt id="cs8fe"><fieldset id="cs8fe"></fieldset></rt>
      <center id="cs8fe"></center>
      <pre id="cs8fe"></pre>
    2. <ul id="cs8fe"><tfoot id="cs8fe"></tfoot></ul>
      <del id="cs8fe"></del>
        <input id="cs8fe"><form id="cs8fe"></form></input>
        国产精鲁鲁网在线视频,国产午夜精品一区二区三区老,日韩av在线高清观看,无码av波多野结衣,国产免费视频一区二区,欧美自慰一级看片免费,亚洲成年轻人电影网站WWW ,成人观看欧美特黄A片
        常識大全

        函數(shù)表達式和函數(shù)聲明有什么不同

        時間:2023-04-01 09:35:23 常識大全

        函數(shù)表達式和函數(shù)聲明有什么不同

          函數(shù)表達式和函數(shù)聲明有什么不同?我們一起看看下面的函數(shù)聲明和函數(shù)表達式的區(qū)別吧!

          我們從一些小測試開始。以下情況都會彈出什么結(jié)果?

          題 1:

          function foo(){

          function bar() {

          return 3;

          }

          return bar();

          function bar() {

          return 8;

          }

          }

          alert(foo());

          題 2:

          function foo(){

          var bar = function() {

          return 3;

          };

          return bar();

          var bar = function() {

          return 8;

          };

          }

          alert(foo());

          題 3:

          alert(foo());

          function foo(){

          var bar = function() {

          return 3;

          };

          return bar();

          var bar = function() {

          return 8;

          };

          }

          題 4:

          function foo(){

          return bar();

          var bar = function() {

          return 3;

          };

          var bar = function() {

          return 8;

          };

          }

          alert(foo());

          如果你的答案不是8、3、3和 [Type Error: bar is not a function] 的話,就繼續(xù)往下讀吧……(即使答對了也要繼續(xù)讀哦)

          什么是 Function Declaration(函數(shù)聲明)?

          Function Declaration 可以定義命名的函數(shù)變量,而無需給變量賦值。Function Declaration 是一種獨立的結(jié)構(gòu),不能嵌套在非功能模塊中?梢詫⑺惐葹 Variable Declaration(變量聲明)。就像 Variable Declaration 必須以“var”開頭一樣,F(xiàn)unction Declaration 必須以“function”開頭。

          e.g.

          function bar() {

          return 3;

          }

          ECMA 5(13.0)定義語法:

          function Identifier ( FormalParameterList[opt] ) { FunctionBody }

          函數(shù)名在自身作用域和父作用域內(nèi)是可獲取的(否則就取不到函數(shù)了)。

          function bar() {

          return 3;

          }

          bar() //3

          bar //function

          什么是 Function Expression(函數(shù)表達式)?

          Function Expression 將函數(shù)定義為表達式語句(通常是變量賦值)的一部分。通過 Function Expression 定義的函數(shù)可以是命名的,也可以是匿名的。Function Expression 不能以“function”開頭(下面自調(diào)用的例子要用括號將其括起來)。

          e.g.

          //anonymous function expression

          var a = function() {

          return 3;

          }

          //named function expression

          var a = function bar() {

          return 3;

          }

          //self invoking function expression

          (function sayHello() {

          alert("hello!");

          })();

          ECMA 5(13.0)定義語法:

          function Identifieropt ( FormalParameterList[opt] ) { FunctionBody }

          (這個定義感覺并不完整,因為它忽略了一個條件:外圍語句是表達式,并且不以“function”開頭)

          函數(shù)名(如果有的話)在作用域外是不可獲取的(與 Function Declaration 對比)。

          那 Function Statement 是什么?

          Function Statement 有時是 Function Declaration 的另一種說法。但是 kangax 指出,在 mozilla 中,F(xiàn)unction Statement 是 Function Declaration 的一種拓展,使得 Function Declaration 語句可以在任何允許使用 statement(語句)的地方使用。但是 Function Statement 現(xiàn)在還不是標準,所以不建議應(yīng)用在產(chǎn)品開發(fā)中。

          現(xiàn)在來解釋下前面的測試。

          Question 1 用了 function declaration,也就是說它們 get hoisted(被提升)了……

          等一下,什么是 Hoisting?

          這里引用 Ben Cherry的話:“Function declaration和function variable(函數(shù)變量)通常會被 JavaScript 解釋器移(‘hoisted’)到當(dāng)前作用域頂部”。

          function declaration 被提升時,整個函數(shù)體都會隨之提升,所以 Question 1 的代碼經(jīng)過解釋器解釋后是像這樣運行的:

          //**Simulated processing sequence for Question 1**

          function foo(){

          //define bar once

          function bar() {

          return 3;

          }

          //redefine it

          function bar() {

          return 8;

          }

          //return its invocation

          return bar(); //8

          }

          alert(foo());

          但是,我們經(jīng)常被告訴說,return 語句后面的代碼是運行不到的啊……

          執(zhí)行 JavaScript 過程中,有 Context(ECMA 5 將之分解為 LexicalEnvironment、VariableEnvironment 和 ThisBinding)和 Process(一系列按序調(diào)用的語句)兩個概念。當(dāng)程序進入執(zhí)行域時,Declaration 會造成 VariableEnvironment。它們不同于 Statement(比如 return),也不遵循 Statement 的運行規(guī)則。

          Function Expression 會被提升嗎?

          這取決于表達式。比如 Question 2 中的第一個表達式:

          var bar = function() {

          return 3;

          };

          等號左邊的(var bar)是 Variable Declaration。Variable Declaration 會被提升,但是 Assignment Expression(賦值表達式)不會。所以當(dāng) bar 提升時,解釋器會這樣初始化:var bar = undefined。而函數(shù)定義本身不會被提升。

          (ECMA 5 12.2 帶有 initialzier(初始化器)的變量是在 VariableStatement 執(zhí)行時,由 AssignmentExpression 賦值的,而不是在變量被創(chuàng)建時。)

          因此 Question 2 的代碼會按以下順序運行:

          //**Simulated processing sequence for Question 2**

          function foo(){

          //a declaration for each function expression

          var bar = undefined;

          var bar = undefined;

          //first Function Expression is executed

          bar = function() {

          return 3;

          };

          // Function created by first Function Expression is invoked

          return bar();

          // second Function Expression unreachable

          }

          alert(foo()); //3

          你可能會說,這還能解釋的通,但是 Question 3 的答案錯了,我在 Firebug 運行會報錯。

          把代碼保存在 HTML 文件中,之后在 Firefox 上運行試試;蛘咴 IE8、Chrome 或 Safari 控制臺中運行。顯然 Firebug 控制臺在“global(全局)”作用域(實際并不是全局的,而是特有的“Firebug”作用域——試著在 Firebug 控制臺中運行“this == window”你就知道了)運行代碼時,不會將函數(shù)提升。

          Question 3 和 Question 1 的邏輯相似。這次是 foo 函數(shù)被提升了。

          Question 4 就很簡單了,根本就沒有函數(shù)提升……

          可以這么說,但是如果根本沒有提升的話,TypeError 會是“bar not defined”,而不是“bar not a function”。此例中確實沒有函數(shù)提升,但是有變量提升。因此 bar 在開始就被聲明了,但是它的值并沒有定義。其它代碼都是按順序執(zhí)行的。

          //**Simulated processing sequence for Question 4**

          function foo(){

          //a declaration for each function expression

          var bar = undefined;

          var bar = undefined;

          return bar(); //TypeError: "bar not defined"

          //neither Function Expression is reached

          }

          alert(foo());

          還應(yīng)該注意什么?

          官方是禁止在非功能模塊(比如 if)中使用 Function Declaration 的。但是所有瀏覽器都支持,但是各自的解釋方式不同。

          例如下面的代碼段在 Firefox 3.6 中會拋錯,因為它將 Function Declaration 解釋成了 Function Statement(見上文),所以 x 沒有定義。但是在 IE8、Chrome 5 和 Safari 5 中,會返回函數(shù) x(和標準的 Function Declaration 一樣)。

          function foo() {

          if(false) {

          function x() {};

          }

          return x;

          }

          alert(foo());

          可以看出使用 Function Declaration 可能會引起混淆,那么它有什么優(yōu)點嗎?

          你可能會說 Function Declaration 很寬松啊——如果試圖在聲明前使用函數(shù),提升確實可以修正順序,以便函數(shù)可以正確調(diào)用。但是這種寬松不利于嚴謹?shù)木幋a,從長遠的角度來看,很有可能會促進而不是阻止意外的發(fā)生。畢竟,程序員按特定的順序排列語句是有原因的。

          那么還有其它理由支持 Function Expression 的嗎?

          你猜呢?

          1)Function Declaration 感覺像是要模仿 Java 風(fēng)格的方法聲明,但是 Java 方法和 JavaScript 并不一樣。在 JavaScript 中,函數(shù)是含值的 living 對象。Java 方法僅是對元數(shù)據(jù)的存儲。下面的兩段代碼都定義了函數(shù),但是只有 Function Expression 看著像創(chuàng)建了對象。

          //Function Declaration

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

          //Function Expression

          var add = function(a,b) {return a + b};

          2)Function Expression 用處更多。Function Declaration 只能作為“statement”孤立存在。它所能做的就是創(chuàng)建一個當(dāng)前作用域下的對象變量。相比之下,F(xiàn)unction Expression(根據(jù)定義)是大型結(jié)構(gòu)的一部分。如果想要創(chuàng)建匿名函數(shù)、給 prototype(原型)添加函數(shù)或是將函數(shù)用作其它對象的 property(屬性),都可以用 Function Expression。每當(dāng)用高階應(yīng)用,比如 curry 或 compose,創(chuàng)建新的函數(shù)時都是在用 Function Expression。Function Expression 和 Functional Programming(函數(shù)式編程)分不開。

          //Function Expression

          var sayHello = alert.curry("hello!");

          Function Expression 有缺點嗎?

          Function Expression 創(chuàng)建的函數(shù)大多是匿名的。比如下面的函數(shù)是匿名的,today 只是一個匿名函數(shù)的引用:

          var today = function() {return new Date()}

          這會有問題嗎?多數(shù)情況下不會,但是就像 Nick Fitzgerald 指出的,調(diào)試匿名函數(shù)會很煩。他建議使用 Named Function Expressions (NFEs)作為工作區(qū):

          var today = function today() {return new Date()}

          但是如 Asen Bozhilov 所說(和 Kangax 文檔)NFEs 在 IE9 以下無法正確執(zhí)行。

          結(jié)論

          隨意放置的 Function Declaration 具有誤導(dǎo)性,并且很少有(如果有的話)情況,用 Function Expression 給變量賦值無法替代 Function Declaration。但是如果必須使用 Function Declaration 的話,將其放在所屬作用域頂部可以減少混淆。永遠不要把 Function Declaration 放在 if 語句中。

          說了這么多,可能在你自己的情況下,F(xiàn)unction Declaration 還是很有用的。這沒什么。死記教條是危險的,并且通常會造成代碼拐彎抹角。更重要的是你理解了概念,這樣就可以根據(jù)自身情況決定用哪種方式創(chuàng)建函數(shù)。我希望此文在這方面有幫助。

          歡迎討論。如果你覺得我哪里說的不對或是有所補充,請聯(lián)系我。

          同見 第5版 ECMA-262 的 10.5、12.2、13.0、13.2 部分

        【函數(shù)表達式和函數(shù)聲明有什么不同】相關(guān)文章:

        函數(shù)聲明與表達式10-01

        確定一次函數(shù)的表達式的數(shù)學(xué)教案10-07

        函數(shù)的教案10-07

        分段函數(shù)09-30

        正弦函數(shù)、余弦函數(shù)的圖象教案10-07

        關(guān)于函數(shù)復(fù)習(xí)課的感受和收獲10-08

        函數(shù)的教案范文10-07

        映射與函數(shù)教案10-07

        冪函數(shù)教案10-07

        主站蜘蛛池模板: 日韩精品无码不卡无码| 亚洲AV无码乱码精品| 亚洲 制服 丝袜 无码| 翁虹19禁全黄无删减版| 国内精自视频品线一二区| yjizz视频网站在线观看| 久久av色欲av久久蜜桃网| 四虎国产精品永久在线下载| 777欧美| 乱子轮熟睡1区| 欧美日韩一区二区三区韩大 | 国产美女精品自在线拍免费| 亚洲成在线aⅴ免费视频| 欧美人成精品网站播放| 国产又粗又猛又爽视频| 在线综合网| 日本337p欧洲亚洲精品| 亚洲中文字幕日产无码2021| 色悠久久网国产精品99| 中文屏幕乱码av| 日本人妻伦在线中文字幕| 高清欧美日韩第一摸| 午夜神器18以下不能进| 无码国产午夜福利片在线观看| 免费人成网站免费看视频| 国产老女人乱淫免费可以| 久久久精品| 日韩不卡免费视频| 日韩成人无码v清免费| 久久久久久网久久久合久久久| 八个少妇沟厕小便漂亮各种大屁股 | 4虎影视国产在线观看精品| 亚洲伊人天堂| 久久综合精品国产二区无码| av亚洲一区| 亚洲精品国产自在久久| 亚洲va精品va国产va| 免费看女人与善牲交| 对白脏话肉麻粗话av| 人妻丰满AV无码中文字幕| 成人 在线 视频自拍|