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干不说,还让代码的不肯定性提高。

相关文章
相关标签/搜索