废话不说,直接上代码(这是在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. 安卓初級教程(4):sqlite建立資料庫

    2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ...

  2. Expert 诊断优化系列------------------冤枉磁盘了

    现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高.软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治.开发人员解决数据问题基本又是 ...

  3. Tomcat无故自动退出的问题

    我在这篇文章<写一个脚本,自动启动Tomcat>中提到Tomcat会无缘无故退出,而且在日志中找不到原因.后来终于知道为什么了: 由于内存不足,被OOM Killer杀死的!由于是直接被系 ...

  4. ASP.NET MVC 过滤器(一)

    ASP.NET MVC 过滤器(一) 前言 前面的篇幅中,了解到了控制器的生成的过程以及在生成的过程中的各种注入点,按照常理来说篇幅应该到了讲解控制器内部的执行过程以及模型绑定.验证这些知识了.但是呢 ...

  5. 图解C#的值类型,引用类型,栈,堆,ref,out

    C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜 ...

  6. 测试框架Mocha与断言expect

    测试框架Mocha与断言expect在浏览器和Node环境都可以使用除了Mocha以外,类似的测试框架还有Jasmine.Karma.Tape等,也很值得学习. 整个项目源代码: 为什么学习测试代码? ...

  7. 【WP开发】加密篇:单向加密

    单向加密,简单地说就是对数据进行哈希处理,平时我们见得较多的有MD5.SHA1等,都属于单向加密.上一篇文章中,老周跟大家扯了有关双向加密的事,本文咱们就扯一下单向加密吧. 要对数据进行哈希处理也不是 ...

  8. ScrollView 嵌套ListView、RecyclerView(持续更新)

    ListView: 只要重写ListView或GridView的onMeasure()方法即可: @Override protected void onMeasure(int widthMeasure ...

  9. 深入理解javascript对象系列第三篇——神秘的属性描述符

    × 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...

  10. iOS开发之版本控制(SVN)

    版本控制对于团队合作显得尤为重要,那么如何在iOS开发中进行版本控制呢?在今天的博客中将会介绍如何在MAC下配置SVN服务器,如何导入我们的工程,如何在Xcode中进行工程的checkOut和Comm ...