关于变量提高,之前在一些教程和书籍上都听到过,平时开发中也知道有这个规律,可是今天忽然在一个公开课中听到时,第一反应时一脸懵逼,而后一百度,瞬间以为好熟悉啊,差点被这个概念给唬住了,不信我给你看个栗子,你也会恍然大悟的:html
(function(){ console.log(v); var v = 'I love you'; console.log(v); })() // undefined I love you
这就是一个典型的变量提高的例子了,规则是怎样的呢,个人理解是在一个做用域内,不管你在哪一个地方声明的变量都会被提高到顶部,但不会赋值。像本例子中的v就是先被提高到了函数做用域的顶端,因此实际运行过程是这样的:函数
(function(){ var v = undefined; console.log(v); v = 'I love you'; console.log(v); })() // undefined I love you
为何会这样呢,我参考了别人的解释是由于js的运行机制:ui
js自上而下的执行过程分为两个词法分析和执行两个阶段:词法分析主要包括:分析形参、分析变量声明、分析函数声明三个部分.经过词法分析将咱们写的js代码转成能够执行的代码,接下来才是执行。code
变量提高还有一种状况,就是函数,词法分析的时候关于函数声明的处理与变量声明的处理不太一致,会一步到位的给当前函数活动对象增长对应函数名的属性,并重写该方法。也就是不会像变量那样先赋值undefined了。说的有点绕,咱们仍是看代码,能够先本身看一下执行结果,再看下面的分析:htm
function a(){ var b = 'a'; function b(){ console.log('b') } alert(b) } a()
简单说下,词法分析时对function b的处理:给当前函数活动对象obj增长属性b,并赋值。即:obj.a = function(){...}; 因此词法分析后的结果成了这个样子:对象
function a(){ var b = undefined; b = function b(){ console.log('b') } b = 'a'; alert(b); // a } a()
这个地方也只是我读别人观点的一种借鉴,可是我有点不太肯定的是普通变量提高和函数提高同时进行时到底谁在最顶端?反正就目前个人认识变量提高的规律是清楚了,大提高提高的原理是由于JS运行机制的问题,为了尽可能避免变量提高带来的一些困扰,平常开发中文名仍是要养成先声明再使用的好习惯,尽可能在函数开头把全部变量都声明出来。文中观点大都是我的理解,若有不对,欢迎指出!blog