关于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. CSS动画与GPU

    写在前面 满世界的动画性能优化技巧,例如: 只允许改变transform.opacity,其它属性不要动,避免重新计算布局(reflow) 对动画元素应用transform: translate3d( ...

  2. xpath爬取网页评论,网址的的调用方法,数据库特殊字符的替换

    # -*- coding:utf-8-*-from lxml import etreeimport urllibimport jsonimport requestsimport MySQLdbid=0 ...

  3. mysql的约束类型

    1.主键约束 2.非空约束 3.唯一性约束 4.外键约束 5.默认值约束

  4. java环境基础步骤 maven

    1. 下载maven,解压到合适的位置 a. 下载 Maven ,其实就是一个压缩包,解压一下       b. 配置一下环境变量 有两个环境变量可以配置: MAVEN_HOME = D:\maven ...

  5. SpringMVC的controller方法上若需要参数 如User

    Bean: public class User {    private String name;     private String password;    public String getN ...

  6. HDU 2295 Radar (重复覆盖)

    Radar Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  7. ubuntu pip 安装django报错解决

    系统版本 ubuntu  Kylin 16.04 LTS       安装pip3 安装 Django 总是提示time out,无法安装. 逛了好多论坛终于遭到了解决办法,分享保存: sudo pi ...

  8. 安装YouCompleteMe

    1. from software center 1 $ apt-get install vim vim-youcompleteme vim-addon-manager 2 $ vam install ...

  9. c#.net全站防止SQL注入类的代码

    using System;using System.Collections.Generic;using System.Linq;using System.Web; /// <summary> ...

  10. OPENQUERY 无行返回 无数据返回 数据缺失

    用SQL Server 2008 R2 的 Oracle Provider for OLE DB 链接Oracle . 在SQL Server中使用下面查询语句,没有数据返回 但是再PL/SQL中查找 ...