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

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

  此时就会发现不遵守规则的下场了,结果不是你想要的。。当然我们不能说只知道要怎么写就行了。要知其然也要知其所以然,究其原因,就涉及到两个概念js作用域和词法分析了。

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

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

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

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

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

语法分析之后的结果如下:

function a(){
var a = undefined;//词法分析之后的结果
alert(a);
a = 'b'
}
a();//undefined

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

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

  我好像忘了说变量提升的概念了,其实上面的就是变量提升的实例了,概念就不去下定义了。大家都知道的。再提一句函数提升,词法分析的时候关于函数声明的处理与变量声明的处理不太一致,会一步到位的给当前函数活动对象增加对应函数名的属性,并重写该方法。也就是不会像变量那样先赋值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'

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

最新文章

  1. 用Kotlin创建第一个Android项目(KAD 01)
  2. sql 分组取最新的数据sqlserver巧用row_number和partition by分组取top数据
  3. 关于mysql安全
  4. makefile 简单介绍
  5. Python之路【第十九篇】:爬虫
  6. JAVA程序1,1,2,3,5,8,13,21....第30个是什么...?
  7. the way of reading English books
  8. Careercup - Google面试题 - 5377673471721472
  9. asp.net出现正在中止线程解决方案
  10. [ Swift框架 ] # SwiftyJSON
  11. MFC DLL中导出函数模板
  12. Nginx网站使用CDN之后禁止用户真实IP访问的方法
  13. About Windows 10 SDK Preview Build 17110
  14. Excel的读取和保存(POI)
  15. hive中beeline取回数据的完整流程
  16. 关于安装 rst2pdf 时遇到的 setuptools过老的问题
  17. MySQL备份可能遇到的坑
  18. linux 网卡
  19. 分布式存储中HDFS与Ceph两者的区别是什么,各有什么优势?
  20. MT【130】Heilbronn问题

热门文章

  1. vs2010 打开 vs2012 的解决方案
  2. 利用qmake生成Makefile文件
  3. jasoncpp读取jason数据如何判断某一字段是否存在
  4. error-2016-2-15
  5. oracle 的 nubmer 类型与 C# 的 float double decimal 对应关系
  6. 在powerdesigner中,一个table,怎么在diagram中创建多个symbol
  7. 找到文字进行标记(replaceWith)
  8. Matrix Calculator
  9. EhCache RMI 分布式缓存/缓存集群
  10. Linux入门学习 常用命令