先看代码(第一个代码片段):

console.log(a);
var a = 1;

如果你认为这是一段不合法的代码,在调用console.log()的时候会输出undefined,你完全正确。但是如果是下面这样呢?

a = 1;
var a;
console.log(a);

结果输出为1.

JavaScript会把var a=1划分为两个语句,var a和a = 1.第一个语句(也就是声明)是在编译阶段处理的,第二个语句(赋值)是在执行阶段处理的。

因此,之前的代码片段实际上是这样执行的:

var a;   //  -------编译阶段

a = 1;     //   -------执行阶段

console.log(a);

而第一个代码片段是这样执行的:

var a;     //    ----编译阶段

console.log(a);

a= 1;       //   -----执行阶段

如你所见,变量和函数声明在编译阶段被移动到了代码的顶部,这就是常说的“提升”。一定要记住,只有声明才会被提升,而赋值或者其他可执行的逻辑依然保留在原位置。

下面的代码片段展示了函数声明提升:

foo();
function foo(){
  console.log(a); //undefined
  var a =1;
}

因为函数的声明会被提升,因此我们可以在其定义之前就调用该函数。关于提升很重要的一点是,他是以作用域为单位进行的。

提升后的函数foo()会变成下面的样子:

function foo(){
var a;
console.log(a);
a =1;
}

函数表达式并不会像函数声明那样被提升。

函数声明和变量声明都会被提升,但是函数在先,变量在后。

JS中的提升(即变量和函数声明移动到代码顶部)的更多相关文章

  1. 深入探究js中的隐式变量声明

    前两天遇到的问题,经过很多网友的深刻讨论,终于有一个相对可以解释的通的逻辑了,然后我仔细研究了一下相关的点,顺带研究了一下js中的隐式变量. 以下文章中提到的隐式变量都是指没有用var,let,con ...

  2. 浅谈JS中 var let const 变量声明

    浅谈JS中 var let const 变量声明 用var来声明变量会出现的问题: 1. 允许重复的变量声明:导致数据被覆盖 2. 变量提升:怪异的数据访问.闭包问题 3. 全局变量挂载到全局对象:全 ...

  3. js中三种定义变量 const, var, let 的区别

    js中三种定义变量的方式const, var, let的区别 1.const定义的变量不可以修改,而且必须初始化. 1 const b = 2;//正确 2 // const b;//错误,必须初始化 ...

  4. js中escape对应的C#解码函数 UrlDecode

    js中escape对应的C#解码函数 System.Web.HttpUtility.UrlDecode(s),使用过程中有以下几点需要注意   js中escape对应的C#解码函数 System.We ...

  5. JavaScript 中对变量和函数声明提前的演示样例

    如题所看到的,看以下的演示样例(能够使用Chrome浏览器,然后F12/或者右键,审查元素.调出开发人员工具,进入控制台console输入)(使用技巧: 控制台输入时Shift+Enter能够中途代码 ...

  6. JavaScript(1)——变量、函数声明及作用域

    这是我的第一篇博客文章,本人不才,文笔也不好,所以可能写的有点凌乱.有什么不对的地方还望见谅.不过每天进步一小步,总有一天会迈出那一大步.以下内容是我对变量.函数声明及函数表达式.作用域的理解. [变 ...

  7. js中var的有或无--重复声明和以后的声明

    js中var的有或无--重复声明和以后的声明 使用var语句多次声明一个变量不仅是合法的,而且也不会造成任何错误. 如果重复使用的一个声明有一个初始值,那么它担当的不过是一个赋值语句的角色. 如果重复 ...

  8. JavaScript中变量和函数声明的提升

    现象: 1.在JavaScript中变量和函数的声明会提升到最顶部执行. 2.函数的提升高于变量的提升. 3.函数内部如果用var声明了相同名称的外部变量,函数将不再向上寻找. 4.匿名函数不会提升. ...

  9. js变量和函数声明的提升

    函数声明和变量声明总是会被解释器悄悄地被“提升”到方法体的最顶部 请注意,变量赋值并没有被提升,只是声明被提升了. 函数的声明比变量的声明具有高的优先级. 下面的程序是什么结果? var foo =  ...

随机推荐

  1. jquery+layer实现无刷新、删除功能(laravel框架)

    先来看一下效果 路由代码 Route::get('car/{id}/delete', 'CarController@delete'); 控制器层代码 //删除汽车信息 public function ...

  2. linux环境jacoco接入

    我们通常会将测试覆盖率分为两个部分,即“需求覆盖率”和“代码覆盖率”. 需求覆盖:指的是测试人员对需求的了解程度,根据需求的可测试性来拆分成各个子需求点,来编写相应的测试用例,最终建立一个需求和用例的 ...

  3. scw——02错误initializationError(Runner:JUnit 4)

    代码: 错误: 原因:版本不同,自动生成的代码不同 解决:

  4. CAN报文格式

    CAN协议的报文传输过程中有:数据帧.远程帧.错误帧.过载帧和帧间隔. 1.数据帧:用于发送节点向接收节点传送数据的帧. 2.远程帧:用于接收节点向具有相同ID的发送节点传送数据的帧. 3.错误帧:用 ...

  5. Django_模型

    1. ORM 2. 简单使用 3. 外键 2.0以上的版本要这样写s_grade = models.ForeignKey(Grade,on_delete=models.CASCADE) 3. 修改表名 ...

  6. Go_Context

    如何通知子goroutine退出? 1. 使用全局变量 package main import ( "fmt" "sync" "time" ...

  7. awk从放弃到入门(1):awk基础

    一.awk简介 awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母.实际上 AWK 的确拥有自己的语言: AWK ...

  8. 为什么Oracle等数据库软件可以同时创建多个连接

    首先我们要明确的是一个IP跟一个端口确定的是一个进程的地址,也就是我们运行了一个Oracle的数据库,这时候就已经确定的了. oracle监听器也是一个TCP/IP网络中的进程,默认的端口号是1521 ...

  9. python 把list中的所有元素串起来变为字符串

    list1=['2','3','4'] s=''.join(list1) print(s) '234'   把元素都变为字符串  list2=[3,4,5] list2=[str(i) for i i ...

  10. idea中使用Data Source and Drivers时,如果使用自己自定义的jar包