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