摘要:而函數(shù)表達(dá)式的值是在運行時確定,并且在表達(dá)式賦值完成后,該函數(shù)才能調(diào)用。
Javascript定義函數(shù)有兩種類型 函數(shù)聲明
// 函數(shù)聲明 function wscat(type){ return type==="wscat"; }函數(shù)表達(dá)式
// 函數(shù)表達(dá)式 var oaoafly = function(type){ return type==="oaoafly"; }
先看下面這個經(jīng)典問題,在一個程序里面同時用函數(shù)聲明和函數(shù)表達(dá)式定義一個名為getName的函數(shù)
getName()//oaoafly var getName = function() { console.log("wscat") } getName()//wscat function getName() { console.log("oaoafly") } getName()//wscat
上面的代碼看起來很類似,感覺也沒什么太大差別。但實際上,Javascript函數(shù)上的一個“陷阱”就體現(xiàn)在Javascript兩種類型的函數(shù)定義上。
JavaScript 解釋器中存在一種變量聲明被提升的機制,也就是說函數(shù)聲明會被提升到作用域的最前面,即使寫代碼的時候是寫在最后面,也還是會被提升至最前面。
而用函數(shù)表達(dá)式創(chuàng)建的函數(shù)是在運行時進行賦值,且要等到表達(dá)式賦值完成后才能調(diào)用
var getName//變量被提升,此時為undefined getName()//oaoafly 函數(shù)被提升 這里受函數(shù)聲明的影響,雖然函數(shù)聲明在最后可以被提升到最前面了 var getName = function() { console.log("wscat") }//函數(shù)表達(dá)式此時才開始覆蓋函數(shù)聲明的定義 getName()//wscat function getName() { console.log("oaoafly") } getName()//wscat 這里就執(zhí)行了函數(shù)表達(dá)式的值
所以可以分解為這兩個簡單的問題來看清楚區(qū)別的本質(zhì)
var getName; console.log(getName)//undefined getName()//Uncaught TypeError: getName is not a function var getName = function() { console.log("wscat") } var getName; console.log(getName)//function getName() {console.log("oaoafly")} getName()//oaoafly function getName() { console.log("oaoafly") }
這個區(qū)別看似微不足道,但在某些情況下確實是一個難以察覺并且“致命“的陷阱。出現(xiàn)這個陷阱的本質(zhì)原因體現(xiàn)在這兩種類型在函數(shù)提升和運行時機(解析時/運行時)上的差異。
當(dāng)然我們最后要給一個總結(jié):Javascript中函數(shù)聲明和函數(shù)表達(dá)式是存在區(qū)別的,函數(shù)聲明在JS解析時進行函數(shù)提升,因此在同一個作用域內(nèi),不管函數(shù)聲明在哪里定義,該函數(shù)都可以進行調(diào)用。而函數(shù)表達(dá)式的值是在JS運行時確定,并且在表達(dá)式賦值完成后,該函數(shù)才能調(diào)用。這個微小的區(qū)別,可能會導(dǎo)致JS代碼出現(xiàn)意想不到的bug,讓你陷入莫名的陷阱中。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95856.html
摘要:如果提升改變了代碼執(zhí)行的順序,會造成非常嚴(yán)重的破壞。聲明本身會被提升,而包括函數(shù)表達(dá)式的賦值在內(nèi)的賦值操作并不會提升。要注意避免重復(fù)聲明,特別是當(dāng)普通的聲明和函數(shù)聲明混合在一起的時候,否則會引起很多危險的問題 你不知道的JS(上卷)筆記 你不知道的 JavaScript JavaScript 既是一門充滿吸引力、簡單易用的語言,又是一門具有許多復(fù)雜微妙技術(shù)的語言,即使是經(jīng)驗豐富的 Ja...
摘要:如果是聲明中的第一個詞,那么就是一個函數(shù)聲明,否則就是一個函數(shù)表達(dá)式。給函數(shù)表達(dá)式指定一個函數(shù)名可以有效的解決以上問題。始終給函數(shù)表達(dá)式命名是一個最佳實踐。也有開發(fā)者干脆關(guān)閉了靜態(tài)檢查工具對重復(fù)變量名的檢查。 你不知道的JS(上卷)筆記 你不知道的 JavaScript JavaScript 既是一門充滿吸引力、簡單易用的語言,又是一門具有許多復(fù)雜微妙技術(shù)的語言,即使是經(jīng)驗豐富的 Ja...
摘要:函數(shù)提升在里有兩種方式創(chuàng)建函數(shù),通過函數(shù)聲明和函數(shù)表達(dá)式。函數(shù)聲明用指定的參數(shù)來定義函數(shù)。提示不要在中進行函數(shù)聲明。問題輸出兩個都是用函數(shù)聲明的函數(shù),將被提升到的局部作用域頂端。函數(shù)本身將作為函數(shù)聲明在全局范圍內(nèi)提升。 作者關(guān)于提升的話題,總共有兩篇。(后來又有一個討論篇),再次搬過來。水平有限,如果翻譯的不準(zhǔn)確請包涵,并去看原文。下面開始: 這是我之前的關(guān)于提升的文章,標(biāo)題為《用le...
摘要:目錄函數(shù)的聲明函數(shù)的屬性和方法函數(shù)的作用域閉包知識點小結(jié)關(guān)于函數(shù),可以從以下個方面去理解首先,數(shù)據(jù)類型上看函數(shù)在中是一種數(shù)據(jù)類型,是對象的一種其次,從功能上看函數(shù)本質(zhì)上是一段反復(fù)調(diào)用的代碼塊最后,從地位上看函數(shù)在中和其他基本數(shù)據(jù)類型一樣,可 目錄 1.函數(shù)的聲明 2.函數(shù)的屬性和方法 3.函數(shù)的作用域 4.閉包知識點 5.小結(jié) 關(guān)于函數(shù),可以從以下3個方面去理解:首先,數(shù)據(jù)類型上看:...
摘要:關(guān)于循環(huán)和閉包當(dāng)循環(huán)和閉包結(jié)合在一起時,經(jīng)常會產(chǎn)生讓初學(xué)者覺得匪夷所思的問題。閉包是一把雙刃劍是比較難以理解和掌握的部分,它十分強大,卻也有很大的缺陷,如何使用它完全取決于你自己。 在談閉包之前,我們首先要了解幾個概念: 什么是函數(shù)表達(dá)式? 與函數(shù)聲明有何不同? JavaScript查找標(biāo)識符的機制 JavaScript的作用域是詞法作用域 JavaScript的垃圾回收機制 先來...
閱讀 2643·2021-11-22 15:24
閱讀 1375·2021-11-17 09:38
閱讀 2752·2021-10-09 09:57
閱讀 1200·2019-08-30 15:44
閱讀 2444·2019-08-30 14:00
閱讀 3543·2019-08-30 11:26
閱讀 2937·2019-08-29 16:28
閱讀 750·2019-08-29 13:56