关于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'

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

js 变量提升和函数提升原理的更多相关文章

  1. 浅谈JS变量声明和函数声明提升

    先来两个问题 很多时候,在直觉上,我们都会认为JS代码在执行时都是自上而下一行一行执行的,但是实际上,有一种情况会导致这个假设是错误的. a = 2; var a; console.log(a); 按 ...

  2. JS 变量提升与函数提升

    JS 变量提升与函数提升 JS变量提升 变量提升是指:使用var声明变量时,JS会将变量提升到所处作用域的顶部.举个简单的例子: 示例1 console.log(foo); // undefined ...

  3. js变量提升与函数提升的详细过程

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  4. JS逻辑题 技术点: 1). 变量提升 2). 函数提升 3). 预处理 4). 调用顺序

    考查的技术点:  1). 变量提升 2). 函数提升  3). 预处理  4). 调用顺序 var c = 1; function c(c) { console.log(c); var c = 3; ...

  5. js中的变量提升和函数提升

    从上周开始,我所在的学习小组正式开始了angular的学习,angular是全面支持es6的,所以语法上和以前的angular有了很大的不同,比如变量声明时就抛弃了var,而选择了let和const: ...

  6. JS——变量提升和函数提升

    一.引入 在了解这个知识点之前,我们先来看看下面的代码,控制台都会输出什么 var foo = 1; function bar() { if (!foo) { var foo = 10; } aler ...

  7. js中变量提升和函数提升

    变量提升和函数提升的总结 我们在学习JavaScript时,会遇到变量提升和函数提升的问题,为了理清这个问题,现做总结如下,希望对初学者能有所帮助 我们都知道 var 声明的变量有变量提升,而 let ...

  8. JavaScript系列文章:变量提升和函数提升

    第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升.这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下. 今天主要介绍以下几点: 1. 变量提升 2. 函 ...

  9. JavaScript:变量提升和函数提升

    第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升.这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下. 今天主要介绍以下几点: 1. 变量提升 2. 函 ...

  10. JavaScript: 变量提升和函数提升

    第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升.这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下. 今天主要介绍以下几点: 1. 变量提升 2. 函 ...

随机推荐

  1. ruby 简介

    Ruby 是一个注重均衡的语言,它的发明者松本行弘 Yukihiro “Matz” Matsumoto,混合了他喜欢的语言(Perl. Smalltalk. Eiffel. Ada 和 Lisp ) ...

  2. Java 名词

    Plain Ordinary Java Object    pojo  简单java对象 Constant   常量 Business Object   BO  业务对象 Framework  框架

  3. 计算机病毒实践汇总六:IDA Pro基础

    在尝试学习分析的过程中,判断结论不一定准确,只是一些我自己的思考和探索.敬请批评指正! 1. IDA使用 (1)搜索.下载并执行IDA Pro,对可执行程序lab05-01.dll进行装载,分别以图形 ...

  4. 使用小米天气API获取天气信息

    1. URL部分 以下url中"%s"代表的是城市Id,比如北京的cityId=101010100: //获取未来五天预报信息,红色部分信息不需要 WEATHER_DATA_URL ...

  5. 开源GIS软件初探

    谈到GIS软件,首先让我们想到的便是GIS界的龙头大哥ESRI公司旗下的ArcGIS产品,从最初接触的version 9.2到如今的version 10.1,其发展可谓风生水起.MapInfo软件也不 ...

  6. 【接口测试】jmeter的使用

    学习地址: https://ke.qq.com/webcourse/index.html#course_id=89002&term_id=100088372&taid=15345918 ...

  7. Android获取时间

    java代码: import java.text.SimpleDateFormat;SimpleDateFormat formatter = new SimpleDateFormat ('yyyy年M ...

  8. EF测试自动修改数据库结构

    1.配置类 <connectionStrings> <add name="test1" connectionString="Data Source=.; ...

  9. HR常用事务代码

    HR TCODE 描述     PA30 维护人力资源主数据 PA40 人事活动

  10. io流导出csv

    @RequestMapping("/doExport") public void doExport(Model model, @RequestParam(value = " ...