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