摘要:執(zhí)行結(jié)果執(zhí)行了函數(shù)同名函數(shù)后者會覆蓋前者函數(shù)執(zhí)行了函數(shù)函數(shù)執(zhí)行了函數(shù)執(zhí)行結(jié)果執(zhí)行了聲明式函數(shù)在預(yù)編譯期聲明函數(shù)及被處理了,所以即使調(diào)用函數(shù)放在聲明函數(shù)前也能執(zhí)行。
if ("a" in window) { var a = 1; } alert(a);
先來看這個題會alert出什么呢?答案很顯然會是:1
不過這道題目放在以前考我的話,那我一定會答錯,后來查找了一番資料,了解到兩個新名詞:預(yù)編譯和變量提升,為了以后不會忘記,還是留個筆記吧。
首先來了解一下什么是預(yù)編譯:對var關(guān)鍵字(值先設(shè)為undefined,執(zhí)行時才給實際值)和函數(shù)定義式進行提前聲明,再接著順序執(zhí)行代碼,函數(shù)定義式在預(yù)編譯時期就被解析,執(zhí)行時期仍然用這個值,而無論是聲明的變量還是聲明式函數(shù),在執(zhí)行的時候,可以覆蓋預(yù)編譯時期的值。
下面我們來解釋一下上面的題目為什么是1呢,首先上面的代碼等價于下面的代碼:
var a; if("a" in window){ a = 1; }
因為js沒有塊級作用域,所以if里面的也是全局的,所以在預(yù)編譯過程中里面的變量a會被提出來并被賦值為undefined,然后在執(zhí)行if語句時候此時a已經(jīng)存在于window中了,只不過值暫時是undefined,于是就會去執(zhí)行if里面的代碼,所以結(jié)果為1;
再來一題:
var a = 1; function a(x){} alert(a); 等價于: var a; a = function(x){} a = 1; alert(a);
預(yù)編譯階段尋找代碼中的var(實際將var a=1拆分為var a;a=1兩部分,第一部分置頂,第二部分掛在語法樹上)以及function兩個關(guān)鍵字并置頂,在此將a以及a()分別置頂,之后在執(zhí)行階段再對a從語法樹進行賦值,最后a為1。
理解了上面的代碼,下面再看一個類似的題目:
function a(x) { return x ; } var a; alert(a); 等價于: var a; function a(x){ return x; } alert(a);
這個題目跟上一個有點類似,但是卻又不同,原因就是在這里a并沒有被賦值,而只是聲明一個變量;在預(yù)編譯階段會將這種形式提前置頂,然后將function也置頂,但是function在a之后,于是預(yù)編譯后二者順序完全倒過來了,所以最后執(zhí)行結(jié)果是function a(x){return x;}。
如果顯式的給a賦值一個a=undefined;那么結(jié)果就是undefined。因為此時牽扯到賦值了 賦值的話 就在執(zhí)行階段去執(zhí)行。
Fn(); //執(zhí)行結(jié)果:"執(zhí)行了函數(shù)2",同名函數(shù)后者會覆蓋前者 function Fn(){ //函數(shù)1 alert("執(zhí)行了函數(shù)1"); } function Fn(){ //函數(shù)2 alert("執(zhí)行了函數(shù)2"); }
Fn(); //執(zhí)行結(jié)果:"執(zhí)行了聲明式函數(shù)",在預(yù)編譯期聲明函數(shù)及被處理了,所以即使Fn()調(diào)用函數(shù)放在聲明函數(shù)前也能執(zhí)行。 function Fn(){ //聲明式函數(shù) alert("執(zhí)行了聲明式函數(shù)"); } var Fn = function(){ //賦值式函數(shù) alert("執(zhí)行了賦值式函數(shù)"); }
通過對比上面兩段代碼,我們不難發(fā)現(xiàn),聲明式函數(shù)與賦值式函數(shù)的區(qū)別在于:在JS的預(yù)編譯期,聲明式函數(shù)將會先被提取出來,然后才按順序執(zhí)行js代碼,所以才有這樣的結(jié)果。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78330.html
摘要:預(yù)編譯發(fā)生在函數(shù)執(zhí)行前也就是說函數(shù)執(zhí)行時,預(yù)編譯已經(jīng)結(jié)束。五總結(jié)理解預(yù)編譯需要明白變量函數(shù)聲明和變量賦值。預(yù)編譯階段,只進行變量函數(shù)聲明,不會進行變量的初始化即變量賦值,所有變量的值都是變量賦值是在解釋執(zhí)行階段才進行的。 一、JS的概念 JavaScript ( JS ) 是一種具有函數(shù)優(yōu)先的輕量級解釋型或即時編譯型的編程語言。 二、JS語言特點 2.1 單線程 (1)JavaScri...
摘要:轉(zhuǎn)載文章公司的平臺功能越堆越多,打包也越來越費勁,一次十幾分鐘,運維很不爽,搗鼓了一下預(yù)編譯,試了一下大概縮短了七八分鐘,目前感覺還行,現(xiàn)在把它記下來,給需要的童鞋當(dāng)做參考,也給自己記錄一下。 (轉(zhuǎn)載文章)公司的平臺功能越堆越多,打包也越來越費勁,一次十幾分鐘,運維很不爽,so搗鼓了一下預(yù)編譯,試了一下大概縮短了七八分鐘,目前感覺還行,現(xiàn)在把它記下來,給需要的童鞋當(dāng)做參考,也給自己記錄...
摘要:大家都知道是解釋型語言,既然是解釋型語言,就是編譯一行,執(zhí)行一行,那又何來預(yù)編譯一說呢腳本執(zhí)行引擎都做了什么呢今天我們就來看看吧。全局域就是一切聲明的全局變量,全是的屬性等同于函數(shù)預(yù)編譯發(fā)生在函數(shù)執(zhí)行前一刻。 大家都知道JavaScript是解釋型語言,既然是解釋型語言,就是編譯一行,執(zhí)行一行,那又何來預(yù)編譯一說呢?腳本執(zhí)行js引擎都做了什么呢?今天我們就來看看吧。 1-JavaScr...
摘要:所以覺得把這個執(zhí)行的詳細(xì)過程整理一下,幫助更好的理解。類似的語法報錯的如下圖所示三預(yù)編譯階段代碼塊通過語法分析階段之后,語法都正確的下回進入預(yù)編譯階段。另開出新文章詳細(xì)分析,主要介紹執(zhí)行階段中的同步任務(wù)執(zhí)行和異步任務(wù)執(zhí)行機制事件循環(huán)。 一、概述 js是一種非常靈活的語言,理解js引擎的執(zhí)行過程對于我們學(xué)習(xí)js是非常有必要的。看了很多這方便文章,大多數(shù)是講的是事件循環(huán)(event loo...
摘要:所以變量聲明提升和函數(shù)聲明提升會出現(xiàn)一個先后順序預(yù)編譯過程結(jié)束。 先科普: 1.javaScript是解釋型語言,就是編譯一行,執(zhí)行一行.....2.javaScript沒有塊級及作用域......3.javaScript具有變量和函數(shù)聲明提升功能.....4.AO對象和GO對象....5.預(yù)編譯就是解決代碼執(zhí)行順序問題,與java語言類似(jvm).... 例如: (function...
閱讀 856·2019-08-30 15:54
閱讀 3322·2019-08-29 15:33
閱讀 2707·2019-08-29 13:48
閱讀 1229·2019-08-26 18:26
閱讀 3341·2019-08-26 13:55
閱讀 1492·2019-08-26 10:45
閱讀 1174·2019-08-26 10:19
閱讀 313·2019-08-26 10:16