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

  1. function a(){
  2. alert(a);
  3. var a = 'b'
  4. }
  5. 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。

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

  1. function a(){
  2. var a = undefined;//词法分析之后的结果
  3. alert(a);
  4. a = 'b'
  5. }
  6. a();//undefined

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

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

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

  1. function a(){
  2. var b = 'a';
  3. function b(){
  4. console.log('b')
  5. }
  6.  
  7. alert(b)
  8. }
  9. a()

  简单说下,词法分析时对function b的处理:给当前函数活动对象obj增加属性b,并赋值。即:obj.a = function(){...}

  所以词法分析后的结果成了这个样子:

  1. function a(){
  2. var b = undefined;
  3. b = function b(){
  4. console.log('b')
  5. }
  6. b = 'a';
  7. alert(b)
  8. }
  9. 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. DSP下的#program

    2014年7月22日 最近调试使用TMS320C6713的片子调试SDRAM,中间经过很多波折,这里就不吐槽了. 想将数据或者代码放到SDRAM上一定要用到#pragma .查阅资料后,感觉百度文库的 ...

  2. machine learning 笔记 normal equation

    theta=(Xt*X)^-1 Xt*y x is feature matrix y is expectation

  3. Oracle游标--cursor_01-简单不带参数实现功能

    对于游标这个概念,可以理解为类似我们以前学习的jdbc的结果集对象, 我们可以使用游标对结果集从上到下进行遍历,获取每一行内容 首先我们要分析一下游标的分类 带参数的 书写函数的整体架构 定义游标 开 ...

  4. linux一些目录功能

    (1)/etc     ----存放配置文件和子目录 (2)/dev     -----是linux的外设文件,dev是devxe(设备)的缩写,在这个目录下存放的是所有linux的外设文件,.在li ...

  5. Spark 读取HBase和SolrCloud数据

    Spark1.6.2读取SolrCloud 5.5.1 //httpmime-4.4.1.jar // solr-solrj-5.5.1.jar //spark-solr-2.2.2-20161007 ...

  6. Android(Intent 学习)

    Intent 是一个消息传递对象,Intent可以通过多种方式促进组件之间的通信,基本的三种用例: 启动Acitivity: Activity表示应用中的一个屏幕,通过将Intent传递给startA ...

  7. thon_sklearn机器学习库学习笔记(四)decision_tree(决策树)

    # 决策树 import pandas as pd from sklearn.tree import DecisionTreeClassifier from sklearn.cross_validat ...

  8. ABP mapto 映射

    obj1.MapTo(obj2); obj1=>obj2: 在obj1实体里添加映射 [AutoMap(typeof(obj2))] public class obj1 { }

  9. 第九周PSP

     工作周期:11.10-11.17 本周PSP: C类型 C内容 S开始时间 ST结束时间 I中断时间 T净时间(分) 文档 写随笔(PSP) 19:00min 22:00min 30min 90mi ...

  10. 我 && yii2(日志埋点,邮件提醒)

    今天试着把yii2 的日志,如果发送邮件的形式实现,具体实现如下 1.环境介绍 lnmp php5.6, mysql5.5, lnmp1.2 yii2-advanced 2.配置文件的编写 在fron ...