js一個"a" in window引起的問題

故事背景

今天看了tom大叔的一篇文章 還有司徒正美的文章,其中講到一些關於javascript的小技巧的題,比較有趣,都有一些繞,不過很好理解。javascript

可是隻有一道題讓我琢磨半天,並非很難,可是從一開始分析方向就錯了,因此記錄下來分享。html

if (!("a" in window)) {
    var a = 1;
}
console.log(a)
複製代碼

就這樣的一道題,問的就是a輸出什麼?

一些老的javascript選手已經作出了答案,輸出是一個undefined。但究竟爲何是undefined呢?java

最開始我思考,由於Javascript沒有塊級做用域,因此if裏面定義的var a = 1;必定是會傳入到window對象裏面的,因此a的輸出必定是1。固然這道題不可能這麼簡單,想固然的就把這幾行代碼輸入到控制檯,輸出一下,發現輸出的是undefinedruby

赤裸裸的打臉讓我羞紅了臉龐,怎麼會這樣,難道 in 操做符有什麼詭異的操做嗎?趕忙搜了一下in操做符,趕忙查看一下,有沒有什麼鮮爲人知的js小技巧。函數

很快撇清了懷疑,由於並無關於操做符引起的詭異事件。既然如此,那必定是發生在window"a"上面了!ui

爲了清晰的查看發生了什麼,我把var a 改爲了var b,發現竟然奇蹟般地能夠輸出正確結果了。使人詫異的同時,也讓我發現了看來和裏面的 var a 有關,因而我定睛一看,發現並非 in 操做符的問題,而是 var的問題spa

var 致使的變量提高

題目已經給出了答案,本題本質上是 var 帶來的變量提高code

// var a; 已經存在
if (!("a" in window)) {
//並無進到這裏
    var a = 1;
} else {
//進入了這裏
}
console.log(a)
複製代碼

同時引出另外一個問題,最初忽略變量提高最大的緣由在於if (!("a" in window))這句代碼,自己是一個判斷,a是否存在於window對象當中。所以,即便a === undefined 返回的也是truecdn

既然布爾值是true,其實也就走不到var a = 1;這一步了。這道題使人迷惑的緣由在於明明 if語句沒能走下去,卻依然被var a = 1;這句話帶來的影響而形成問題。htm

變量提高帶來的問題

JavaScript 中,函數及變量的聲明都將被提高到函數的最頂部。

JavaScript 中,變量能夠在使用後聲明,也就是變量能夠先使用再聲明。

變量提高(Hoisting)被認爲是, Javascript中執行上下文 (特別是建立和執行階段)工做方式的一種認識。在 ECMAScript® 2015 Language Specification 以前的JavaScript文檔中找不到變量提高(Hoisting)這個詞。不過,須要注意的是,開始時,這個概念可能比較難理解,甚至惱人。

例如,從概念的字面意義上說,「變量提高」意味着變量和函數的聲明會在物理層面移動到代碼的最前面,但這麼說並不許確。實際上變量和函數聲明在代碼裏的位置是不會動的,而是在編譯階段被放入內存中。

因爲if判斷語句存在 window做用域下,所以變量提高依然生效,正由於沒有塊級做用域,因此存在於if中的var會提高到,window對象下。

總結

如此說來本題也就解開了,一道由變量提高引起的謎題。最初卻被迷魂湯迷住了雙眼,正是因爲對if判斷條件的信任才致使沒法理解代碼的走向。

這是一道很早以前的小題,咱們在平常寫代碼的時候通常也會格外注意做用域問題,並且大多數狀況不會使用in來判斷。但假如真的須要使用,那就不得不注意變量提高致使的,in操做符判斷的不肯定性,一道小題,幾分鐘迷人眼,但若是是一個大型組件,一時半會還真不那麼容易找到問題來源,浪費c幹不說,還讓代碼的不肯定性提高。

相關文章
相關標籤/搜索