js 变量提高和函数提高原理

 关于js的变量,开始的时候咱们都会被告知,变量声明应该在引用该变量以前。关于为何要这样作呢,开始的时候本着会用就行的目的,也没去深究。不事后来常常会发现一些让人很费解的。。姑且称为现象吧。先看一段代码再说:html

function a(){
    alert(a);
    var a = 'b'
}
a();//undefined

  此时就会发现不遵照规则的下场了,结果不是你想要的。。固然咱们不能说只知道要怎么写就好了。要知其然也要知其因此然,究其缘由,就涉及到两个概念js做用域和词法分析了。c++

  都知道js中不存在相似于c++等语言的块级做用域,例如for循环中定义的变量,实际上是属于当前对象下的属性,同一对象下能够随便访问。只有函数能够限定一个变量的做用范围,即函数才是变量的做用域。对于函数的变量访问时遵循做用域链的。函数

  js自上而下的执行过程分为两个词法分析执行两个阶段:词法分析主要包括:分析形参、分析变量声明、分析函数声明三个部分(具体关于js词法分析这里知识简单说明,请查看个人另外一篇文章http://www.cnblogs.com/pqjwyn/p/5365532.html)。经过词法分析将咱们写的js代码转成能够执行的代码,接下来才是执行。post

  通过词法分析的后两个步骤,会将存在的变量声明和函数声明,进行一番处理。具体拿上面的代码作个例子(只分析变量的部分):学习

      一、分析形参:此处没有,直接略过(本文只分析变量部分,要是要看完整的部分能够转到http://www.cnblogs.com/pqjwyn/p/5365532.htmlspa

  二、分析变量声明:此处存在var a = 'b'; 则会给当前函数活动对象(obj)增长属性a,即:obj.a = undefined。code

     语法分析以后的结果以下:htm

复制代码
function a(){
    var a = undefined;//词法分析以后的结果
    alert(a);
    a = 'b'
}
a();//undefined
复制代码

  接下来就是执行的过程了,什么你说alert()语句呢?词法分析顾名思义只分析词法相关的部分即变量声明之类的,做为一个执行语句,只有在执行的过程才会执行。也就是说该过程和执行语句还没扯上关系呢,下面执行步骤的时候才会出场。对象

  因此执行的时候自上而下的顺序执行时,当执行到alert(a);时,真正的赋值语句还在下面,因此是undefined。blog

  我好像忘了说变量提高的概念了,其实上面的就是变量提高的实例了,概念就不去下定义了。你们都知道的。再提一句函数提高,词法分析的时候关于函数声明的处理与变量声明的处理不太一致,会一步到位的给当前函数活动对象增长对应函数名的属性,并重写该方法。也就是不会像变量那样先赋值undefined了。说的有点绕,咱们仍是看代码,能够先本身看一下执行结果,再看下面的分析:

复制代码
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()
复制代码

  而后顺序执行的结果也就出来了,b被从新赋值两次以后的结果为'a'

  到此为止,关于变量提高的部分已经结束了。仍是那句话,我的愚见,抛砖引玉,共同窗习,共同进步。转载请注明出处。

如水穿石,厚积才可薄发
相关文章
相关标签/搜索