变量提高基础概念其实很好理解:变量提高即将变量声明提高到它所在做用域的最开始的部分。 可是咱们真的遇到变量提高的题目时,却反而容易遗忘。如:程序员
if (! "a" in window) {
var a = 1;
}
alert(a); //undefined
复制代码
第一遍阅读代码的感受是这样的:若是全局对象中不存在a这个属性没,那么设置全局变量a=1。 那么答案应该等于1才对,为何是undefined呢?
由于a被变量提高了!
再次解析上面代码,其实至关于如下代码:es6
/**
上面这段代码至关于
**/
var a;
if (! "a" in window) {
a = 1;
}
alert(a);
复制代码
首先,咱们须要知道一个概念:js运行时,会分两步进行操做,先进行解析,再执行 。
面试
解析,也就是建立变量和声明函数。js会将全部var定义的变量和function都提高到做用域的顶端。并检查时候有语法错误。如:Uncaught ReferenceError等。segmentfault
执行,js从上向下开始运行代码。
bash
这样咱们就能够清晰地看出a是undefined了。函数
参考自:segmentfault.com/q/101000001…工具
以前一直不理解为何要有变量提高,这只是一个js设计的缺陷吗?若是是缺陷为何不一开始就解决掉他呢?(如今es6已经使用let代替var)他以前有没有什么存在的意义呢?性能
解析的过程当中,还会为函数生成预编译代码。在预编译时,会统计该函数声明了哪些变量、建立了哪些函数(注:这里就是声明提高),并对函数的代码进行压缩,去除注释、没必要要的空白等。这样作的好处是每次执行函数时均可以直接为该函数分配栈空间(不须要再解析一遍去获取函数中声明了哪些变量,注:这也是声明提高的好处),而且代码执行更快(由于压缩而变短了)。两个好处都会提升执行函数的性能。测试
咱们知道,JS是一种脚本语言,在发布以后很长时间内都没有为程序员提供编译器、调试器、语法检查器等工具。在很长一段时间内其地位始终是Web页面的附属品,仅仅用来给页面添加一些非必要的动态效果,而且其开发和部署也具备很强的随意性,未通过调试和测试的代码比比皆是。
spa
简而言之,之前的js并非很被人看好,只当他是个脚本语言,经过这个方法能够简化开发,减小报错,增长容错率。
其实提高功能不可替代的状况是用在函数提高上。如:
function func1() {
func2();
}
fun1();
function func2() {
alert('success');
}
复制代码
这是咱们很常见的申明函数的状况,若是没有函数提高,在执行到fun2()时会直接报错,由于此时func1还并未定义。
那么咱们最后来讨论一下,变量提高真的是设计缺陷吗?
我认为多是的。由于在如今的开发中,变量提高只会加大咱们对代码的理解的难度。 有时候会形成咱们意想不到的问题,形成不是咱们想要的结果,(如上面的题目)并且很难排查。也正如大众对JavaScript的评价就是:它的优秀之处并不是原创,它的原创之处并不优秀。
9道面试题
参考自 www.jianshu.com/p/864b0003d…
写出下列显示的值
(function(){
a = 5;
alert(window.a);
var a = 10;
alert(a);
})();
复制代码
解题过程:这是利用了当即执行函数来模拟块级做用域的写法。由于函数提高就是把变量声明提高到它所在做用域的最开始的部分,因此上面代码至关于:
(function(){
var a; //局部变量a,默认值是undefined
a = 5; //因和局部变量名相同,所以全局变量a被覆盖,此处变成了给局部变量a赋值
//alert(a); 弹出5
//a只是变量,而不是属性 alert(a in window)返回false ,参见http://segmentfault.com/q/1010000002883076 的第一个回答
alert(window.a);
a = 10;
alert(a);
})();
复制代码
因此答案是 undefined和10