关于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. Office 365 系列四 ------ 绑定公司域名

    Office 365包含了企业邮箱服务(Exchange Online),我们如果要用微软的企业邮箱,那么我们必须绑定我们公司的自己域名,而不是用微软 提供的二级域名,其实微软的整个Exchange ...

  2. 粒子拼字效果(getImageData方法)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. #define 小知识

    #define N 15 #define M 2+N #define W 2*M 问3*W的结果是多少? 结果为27: 知识点:define只能进行非常简单的运算,简单来说就是仅仅是将自身的值代入,而 ...

  4. quartz 框架定时任务,使用spring @Scheduled注解执行定时任务

    配置quartz 在spring中需要三个jar包: quartz-1.6.5.jar.commons-collections-3.2.jar.commons-logging-1.1.jar 首先要配 ...

  5. b/s结构的物业管理系统(一)-------登录篇

    最近计划做一个非框架的物业管理系统前端使用bootstrap js jquery 等希望各位指点一下共同学习 ---前端登录页面------ 这个页面的输入框组用的bootstrap的,我设置了几张背 ...

  6. spring web.xml 难点配置总结

    web.xml web.xml是所有web项目的根源,没有它,任何web项目都启动不了,所以有必要了解相关的配置. ContextLoderListener,ContextLoaderServlet, ...

  7. python 协程

    协程 协程就是一种用户态内的上下文切换技术. 1.使用gevent实现协程, gevent.spawn()调用函数,  gevent.sleep(1) 模拟阻塞,实现切换. import gevent ...

  8. Haproxy+Keepalived高可用负载均衡详细配置

    本文所使用的环境: 10.6.2.128    centos6.5 10.6.2.129    centos6.5 VIP  为10.6.2.150 要实现的目标: 实现10.6.2.128和10.6 ...

  9. Amoeba+Mysql实现数据库读写分离

    一.Amoeba 是什么 Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发.座落与Client.DB Server(s)之间.对客户端透明.具有负载均衡.高可用性.sql过滤.读写分离 ...

  10. Thinking in Java 学习笔记(一)

    chapter_01 对象导论 1.1  Java语言基础Smalltalk的特性: 万物皆对象  可以将对象视为一种奇特的变量,它可以存储数据(成员变量),也可以在自身上执行操作(方法). 程序对象 ...