废话不说,直接上代码(这是在JavaScript面对对象编程指南上面看到的一个例子)

var a=123;
function f(){
alert(a);
var a=1;
alert(a);
}
f();

  书上的解释是这样的:当JavaScript执行过程进入新函数时,这个函数内被声明的所有变量都会被移动导到函数最开始的地方。这种现象叫做提升。且被提升的只有变量的声明。

上面这个例子可以等价于:

var a=123;
function f(){
  var a;
  alert(a);
  a=1;
  alert(a);
}
f(); //答案很显然是1

  书上只是把它当做一个定义,告诉读者必须记住。其实我们可以从JavaScript编译器的原理出发,搞清楚这段代码到底是怎么编译的就不用死记了!!

  那么我们就首先简单的谈一下JavaScript代码是怎样编译执行的(浅显的谈)首先JavaScript代码的编译执行主要由JavaScript引擎,编译器,作用域三个负责。

  引擎:从头到尾负责整个JavaScript程序的编译和执行过程;

  编译器:负责语法分析及代码生成等;

  作用域:负责收集并维护由所有声明的变量组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些变量的访问权限。

  可能不是很明白,我们先看一下传统的编译器编译的过程,一段代码执行大概需经过下面三个过程(其实际过程肯定比这复杂很多):

  1,词法分析:将由字符组成的字符串分解成有意义的代码块。而这些代码块被称作词法单元。例如:var a=2;这段代码会被分解成var,a,=,2,;这些词法单元。

  2,语法分析:将词法单元流转换成一个由元素逐级嵌套所组成的代表了程序语法结构的“抽象语法树”;

  3,代码生成:将“抽象语法树”转换成为可执行代码的过程。这个过程与语言和目标平台相关。

  由于JavaScript不同于其他有专用编译器的语言如C(如hello.c是先编译成可执行的hello.0程序,这儿阶段声明赋值都已经操作完成,如果编译成功就能执行。)而JavaScript代码编译阶段只是一个对变量的声明阶段,其赋值什么的操作是在代码实际执行的时候才进行的。这也是为什么JavaScript代码写完后必须执行才能知道有没有错误。

  好了相关概念介绍基本差不多了,那上面这段代码该如何用编译器去理解呢!我们先来简单的理解var a=2;这段代码。首先这段代码由交给编译器:编译器工作就是负责语法分析,它首先会对var a进行声明,然后去它的作用域中寻找之前有没有声明a,如果已经声明了就忽略这个声明,如果没有找到就在作用域中声明一个新的变量a,然后编译器就将代码编译成引擎可以运行的代码,这些代码用来处理a=2;引擎拿到代码后首先会在作用域中寻找有没有a变量,如果有就使用这个变量a,如果没有就会抛出错误。这段过程总结一下就是代码首先在编译器中声明相关变量,然后交给引擎,引擎便对这些变量进行操作(赋值等)。

  有了上面的分析过程我们再来看第一段代码:书上之所以能把它改写成下面那段代码,就是因为这段代码首先会在编译器进行编译,编译的过程就是将这段代码中作用域相关的各个变量进行声明,这是在引擎执行代码前工作的,所以改写的时候var a会提到作用域的最前面,等编译完成后JavaScript引擎才会进一步执行代码也就是对变量进行各种赋值等操作。这个过程就是书上面提到那个词“提升”。其他的一些细节就不用赘述了。第二段代码应该能很清楚的理解了。(注意:提升只能在变量自己的作用域里面提升,不能越过作用域提升到外面来。)。

  再给一个练习的例子:

f();  //Hello World!
var f;
function f(){
  aler("Hello World!");  
}
f=function(){
  alert("Hello Javascript!");
}

  改写形式我就不写了,自己完全可以写出来。

  

关于JavaScript变量提升的理解的更多相关文章

  1. JavaScript变量提升的理解

    变量提升 先说三句总结性的话: let 的「创建」过程被提升了,但是初始化没有提升. var 的「创建」和「初始化」都被提升了. function 的「创建」「初始化」和「赋值」都被提升了. 所以,我 ...

  2. 回归基础: JavaScript 变量提升

    from me: javascript的变量声明具有hoisting机制,它是JavaScript一个基础的知识点,也是一个比较容易犯错的点,平时在开发中,大大小小的项目都会遇到. 它是JavaScr ...

  3. JavaScript变量提升和函数声明预解析

    1.首先理解函数作用域 在JavaScript中,变量的定义并不是以代码块作为作用域的,而是以函数作用作用域的.也就是说,如果变量是在某个函数中定义的,那么它在函数以外的地方是不可见的.而如果该变量是 ...

  4. JavaScript变量提升 面试题

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  5. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

  6. 对javascript变量提升跟函数提升的理解

    在写javascript代码的时候,经常会碰到一些奇怪的问题,例如: console.log(typeof hello); var hello = 123;//变量 function hello(){ ...

  7. 最通俗易懂的javascript变量提升

    a = 'ghostwu'; var a; console.log( a ); 在我没有讲什么是变量提升,以及变量提升的规则之前, 或者你没有学习过变量提升,如果按照现有的javascript理解, ...

  8. JavaScript变量提升及作用域

    今天在知乎看前端面试题的时候,看到这样的问题,发现自己懂的真的是太少了,看了给的例子,所以写一下自己的理解. 首先放一段代码: var v= “hello JavaScript”; alert(v); ...

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

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

随机推荐

  1. CSS基础篇之选择符

    关系选择符 E F 包含选择符(Descendant combinator) CSS1 选择所有被E元素包含的F元素. <html> <head> <meta chars ...

  2. CDN解决方案

    帝联cdn 这算不算是打广告呢?

  3. Hadoop学习笔记—3.Hadoop RPC机制的使用

    一.RPC基础概念 1.1 RPC的基础概念 RPC,即Remote Procdure Call,中文名:远程过程调用: (1)它允许一台计算机程序远程调用另外一台计算机的子程序,而不用去关心底层的网 ...

  4. 玩转动态编译 - 高级篇:二,IL设置静态属性,字段和类型转换

    静态属性赋值 先来看 Reflector反射出的IL源码(感谢Moen的提示),这次用 Release模式编译,去掉那些无用的辅助指令 public void AAA(string s) { MyCl ...

  5. [ASP.NET MVC 小牛之路]08 - Area 使用

    ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块.这对于大的工程非常有用,Area 使每个功能模块都有各自的文件夹,文件夹中有自己的Cont ...

  6. 《Entity Framework 6 Recipes》中文翻译系列 (13) -----第三章 查询之使用Entity SQL

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-4使用实体SQL查询模型 问题 你想通过执行Entity SQL语句来查询你的实 ...

  7. Html5 布局方式

    在Html5之前,统一采用的是Div+css的方式进行布局,但是却和开发人员的命名方式,喜好有关.在新的Html5中,布局却显得更加人性化,更易理解了.如增加了Header,Footer,Sectio ...

  8. 《Spark快速大数据分析》—— 第五章 数据读取和保存

    由于Spark是在Hadoop家族之上发展出来的,因此底层为了兼容hadoop,支持了多种的数据格式.如S3.HDFS.Cassandra.HBase,有了这些数据的组织形式,数据的来源和存储都可以多 ...

  9. css知多少(6)——选择器的优先级

    1. 引言 上一节<css知多少(5)——选择器>最后提到,选择器类型过多将导致一些问题,是什么问题呢?咱们直接举例子说明. 上图中,css中的两个选择器都是针对<span>的 ...

  10. 轻量级前端MVVM框架avalon - 执行流程1

    基本上确定了avalon的几个重要元素的关系: M,即model,一个普通的JS对象,可能是后台传过来的,也可能是直接从VM中拿到,即VM.$json.有关的这个$json的名字还在商讨 V,即Vie ...