摘要:函數(shù)聲明和函數(shù)表達式的區(qū)別函數(shù)聲明只能出現(xiàn)在程序或函數(shù)體內(nèi)。所以,在等語義為語句的代碼塊中存在函數(shù)聲明,由于函數(shù)提升特性,會破壞掉原本的語義。
這篇談一下JS函數(shù)聲明與函數(shù)表達式的區(qū)別及要注意的地方:
函數(shù)聲明主要有兩種類型:
函數(shù)聲明
function fn() {};
函數(shù)表達式
var fn = function () {};
這兩種函數(shù)創(chuàng)建方式有區(qū)別嗎?當(dāng)然有,回想一下變量聲明提升,這里函數(shù)也遵循這個規(guī)則。
JS函數(shù)聲明和函數(shù)表達式的區(qū)別FunctionDeclaration(函數(shù)聲明)只能出現(xiàn)在Program(程序)或FunctionBody(函數(shù)體)內(nèi)。從句法上講,它們 不能出現(xiàn)在Block(塊)({ ... })中,例如不能出現(xiàn)在 if、while 或 for 語句中。因為 Block(塊) 中只能包含Statement(語句), 而不能包含FunctionDeclaration(函數(shù)聲明)這樣的SourceElement(源元素)。
另一方面,仔細看一看產(chǎn)生規(guī)則也會發(fā)現(xiàn),唯一可能讓Expression(表達式)出現(xiàn)在Block(塊)中情形,就是讓它作為ExpressionStatement(表達式語句)的一部分。但是,規(guī)范明確規(guī)定了ExpressionStatement(表達式語句)不能以關(guān)鍵字function開頭。而這實際上就是說,F(xiàn)unctionExpression(函數(shù)表達式)同樣也不能出現(xiàn)在Statement(語句)或Block(塊)中(別忘了Block(塊)就是由Statement(語句)構(gòu)成的)。
由于存在上述限制,只要函數(shù)出現(xiàn)在塊中(像上面例子中那樣),實際上就應(yīng)該將其看作一個語法錯誤,而不是什么函數(shù)聲明或表達式。
那么我們應(yīng)該在什么時候使用函數(shù)聲明或函數(shù)表達式呢?函數(shù)聲明只能出現(xiàn)在“程序代碼”中,意味著只能在其它函數(shù)體中或者全局空間;它們的定義不能不能賦值給一個變量或?qū)傩裕蛘咦鳛橐粋€參數(shù)傳遞出現(xiàn)在函數(shù)調(diào)用中;
Javascript 中函數(shù)聲明和函數(shù)表達式是存在區(qū)別的,函數(shù)聲明在JS解析時進行函數(shù)提升,因此在同一個作用域內(nèi),不管函數(shù)聲明在哪里定義,該函數(shù)都可以進行調(diào)用。
函數(shù)表達式的值是在JS運行時確定,并且在表達式賦值完成后,該函數(shù)才能調(diào)用。這個微小的區(qū)別,可能會導(dǎo)致JS代碼出現(xiàn)意想不到的bug,讓你陷入莫名的陷阱中。
fn(); // "fn" function f n() { console.log("fn") }; fn2(); // "Uncaught TypeError: undefined is not a function" var fn2 = function () { alert("fn2"); };
這段代碼就是對上面文字的解釋。所以,在if、while等語義為語句的代碼塊中存在函數(shù)聲明,由于函數(shù)提升特性,會破壞掉原本的語義。函數(shù)提升后,作用域也會為為該函數(shù)的下的函數(shù)作用域,這樣原本屬于函數(shù)"內(nèi)部"的函數(shù)就變?yōu)橥獠康牧恕?/p>
這里接兩個大神的文章:
函數(shù)聲明和函數(shù)表達式——函數(shù)聲明的聲明提前 - myvin - 博客園
詳解Javascript 函數(shù)聲明和函數(shù)表達式的區(qū)別 - JackWang-CUMT - 博客園
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/83029.html
摘要:你知道中的每條語句甚至表達式都有一個結(jié)果值嗎當(dāng)你在瀏覽器中測試代碼時,經(jīng)常會在控制臺的輸出結(jié)果的最后面多出一條,大部分為,這個就是一個結(jié)果值。特例變量聲明語句函數(shù)聲明語句的結(jié)果值為。 你知道JavaScript中的每條語句、甚至表達式都有一個結(jié)果值嗎? 當(dāng)你在瀏覽器中測試代碼時,經(jīng)常會在控制臺的輸出結(jié)果的最后面多出一條,大部分為undefined,這個undefined就是一個結(jié)果值。...
摘要:不包括作為其嵌套函數(shù)的被解析的源代碼。作用域鏈當(dāng)代碼在一個環(huán)境中執(zhí)行時,會創(chuàng)建變量對象的一個作用域鏈。棧結(jié)構(gòu)最頂層的執(zhí)行環(huán)境稱為當(dāng)前運行的執(zhí)行環(huán)境,最底層是全局執(zhí)行環(huán)境。無限制函數(shù)上下文。或者拋出異常退出一個執(zhí)行環(huán)境。 前言 其實規(guī)范這東西不是給人看的,它更多的是給語言實現(xiàn)者提供參考。但是當(dāng)碰到問題找不到答案時,規(guī)范往往能提供想要的答案 。偶爾讀一下能夠帶來很大的啟發(fā)和思考,如果只讀一...
摘要:大家想想怎么做什么是匿名函數(shù)自執(zhí)行并如何在實際庫中應(yīng)用匿名函數(shù)自執(zhí)行,注意,注意,只有這個名字和沒有其它名字,比如封閉空間,這個是為了讓大家好理解自己造的詞語。 通過本節(jié)課你將學(xué)到: 1.什么是函數(shù)表達式和函數(shù)聲明 2.first-class function 3.引用和復(fù)制的區(qū)別 4.函數(shù)傳參是怎么回事兒 5.關(guān)于函數(shù)的this和arguments 6.什么是匿名函數(shù)自執(zhí)行并如何在...
摘要:從某些方面來講,這章回顧的函數(shù)知識并不是針對函數(shù)式編程者,非函數(shù)式編程者同樣需要了解。什么是函數(shù)針對函數(shù)式編程,很自然而然的我會想到從函數(shù)開始。如果你計劃使用函數(shù)式編程,你應(yīng)該盡可能多地使用函數(shù),而不是程序。指的是一個函數(shù)聲明的形參數(shù)量。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 關(guān)于譯者:...
摘要:從定義函數(shù)說起如何定義函數(shù)一般來說,定義函數(shù)的方式有兩種,分別是函數(shù)聲明和函數(shù)表達式。我們聲明了一個變量,接著又定義了一個函數(shù),我們通過監(jiān)視窗口發(fā)現(xiàn)一直被定義成了一個函數(shù),顯然,函數(shù)聲明的優(yōu)先級高于變量聲明。 從定義函數(shù)說起 如何定義函數(shù)? 一般來說,定義函數(shù)的方式有兩種,分別是函數(shù)聲明和函數(shù)表達式。 //函數(shù)聲明 function foo1() { console.log(h...
閱讀 1049·2021-11-24 09:39
閱讀 3580·2021-11-22 13:54
閱讀 2542·2021-10-11 10:59
閱讀 773·2021-09-02 15:40
閱讀 1025·2019-08-30 15:55
閱讀 1042·2019-08-30 13:57
閱讀 2305·2019-08-30 13:17
閱讀 3025·2019-08-29 18:32