来看如下代码:

function HelloJS(){
var array = [1,2,3,4,5];
for(var i in array){ }
alert(i);
} HelloJS(); alert(i);

  此段代码运行后先执行HelloJS();,会先输出4,然后再执行alert(i);,执行alert(i);时会报i is not defined的错误。

根据变量提升,这段代码等同于如下代码:

function HelloJS(){
var i;
var array = [1,2,3,4,5];
for(i in array){ }
alert(i);
} HelloJS(); alert(i);

可见对应变量i的声明自动提升到了代码块的头部这里即函数的头部,即第一个alert可以正常执行。 

执行第二个alert(i)报错是因为:用var操作符定义的变量将成为定义该变量的作用域中的局部变量。也就是说如果在函数中使用var定义一个变量,那么这个变量在函数退出后就会被销毁。

JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。(只会提升变量的声明语句,不会提升变量的赋值语句,例如var a = 1;只会提升var a;将它放到代码块的头部,而a=1;语句照样在原来的位置)

示例:

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

以上语句并不会报错,只是提示undefined。实际运行过程:

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

表示变量a已声明,但还未赋值。但是变量提升只对var命令声明的变量有效,如果一个变量不是用var命令声明的,就不会发生变量提升。

console.log(b);
b =1;

以上代码将会报错:ReferenceError: b is not defined

与普通变量一样,js里的function也可看做变量,也存在变量提升情况:

abc();

function abc(){
console.log(1);
};

表面上,上面代码好像在声明之前就调用了函数abc。但是实际上,由于“变量提升”,函数abc定义部分被提升到了代码头部,也就是在调用之前已经声明了。但是,如果采用赋值语句定义函数,JavaScript就会报错:

abc();

var abc = function(){
console.log(1);
}; // TypeError: abc is not a function

因为,实际运行过程:

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

这时候abc是个变量,并非function

函数声明可以被提前,如果是函数表达式则只有变量声明提前,函数体并不会提前。

js中的变量提升(hoisting)的更多相关文章

  1. js中的变量提升(Hoisting)

    <script> function test(){ console.log(a); console.log(foo()); var a=1; function foo(){ return ...

  2. JS中的 变量提升

    首先纠正下,文章标题里的 “变量提升” 名词是随大流叫法,“变量提升” 改为 “标识符提升” 更准确.因为变量一般指使用 var 声明的标识符,JS 里使用 function 声明的标识符也存在提升( ...

  3. js中的变量提升和函数提升

    从上周开始,我所在的学习小组正式开始了angular的学习,angular是全面支持es6的,所以语法上和以前的angular有了很大的不同,比如变量声明时就抛弃了var,而选择了let和const: ...

  4. js函数、变量提升(hoisting)

    其实我只是想复习下变量提升的,然后看到了函数提升,然后再看到了函数声明.函数表达式. 有必要怀着敬仰之心提及园子里的TOM大叔的解密命名函数表达式,不愧是大叔,好好地脑补了下基础知识. 在ECMASc ...

  5. js中的变量提升与函数提升

    先看看一个简单的代码 var str='Hello World'; alert(str);//弹出 Hello World 再看一段代码: var v='Hello World'; (function ...

  6. js中的变量提升

    var v='Hello World'; (function(){ alert(v); var v='I love you'; })() 会出现alert出来的是undefined,原因是因为在函数域 ...

  7. JavaScript中变量提升------Hoisting

    原谅链接:http://www.cnblogs.com/damonlan/archive/2012/07/01/2553425.html 因为这个问题很是经典,而且容易出错,所以在介绍一次.哈哈.莫怪 ...

  8. js 中的变量声明提前总结

    一.var 声明 ES6之前,js 中声明变量基本上用 var 关键字: 1.如果访问未声明的变量,会报错:ReferenceError 2.声明了未赋值,值为 undefined,跟前面的报错是两回 ...

  9. JS 会有变量提升和函数提升

    JavaScript变量函数声明提升(Hoisting)是在 Javascript 中执行上下文工作方式的一种认识(也可以说是一种预编译),从字面意义上看,"变量提升"意味着变量和 ...

随机推荐

  1. 合并Dev BPL教程

    一.准备工具 1.Devexpress vcl 14.2.2 下载地址http://download.csdn.net/user/rfjbco,共用个包,下载后解压,程序目录已带有DxAutoInst ...

  2. 拼图游戏js

    实现算法: 1. JavaScript动态生成拼图:通过生成16个div,且除最后一个div不使用背景图片以外,其他div都设置拼图图片为背景.然后通过调整background-position来实现 ...

  3. Mysql 锁技术要点【转载】

    MyISAM和InnoDB的区别 MySQL默认采用的是MyISAM. MyISAM不支持事务,而InnoDB支持.InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事 ...

  4. 防火墙没有关导致外部访问虚拟机的tomcat遇到的问题和解决方法

    部署好tomcat,想在自己电脑上的浏览器访问,但是发现访问不了 访问方式是浏览器地址栏输入ip加端口,我的是192.138.211.121:8080,显示结果是无连接 在电脑上ping一下主机发现是 ...

  5. IntelliJ IDEA小问题解决方法------(持续更新)

    1:IDEA运行时报错提示“找不到或无法加载主类”:在确保IDEA开发环境无误后->file->invalidate Cache/restart,之后再重新build.问题解决. 2.如何 ...

  6. javascript面向对象的程序设计之Object.getOwnPropertyDescriptor()

    Object.getOwnPropertyDescriptor()用于获取给定属性的描述信息,这个描述信息是一个对象. 如果是访问器属性,则这个对象的属性有configurable,enumerabl ...

  7. OpenCV:初试牛刀-带滚动条的视频播放-2

    视频播放时点击窗口关闭按钮(即小叉号)关闭窗口 隐藏console控制台 使用VideoCapture和createTrackbar实现滚动条控制视频播放 #include<iostream&g ...

  8. Django中间件执行流程

    中间件函数是 django 框架为我们预留的函数接口, 让我们可以干预请求和应答的过程 1. 获取浏览器端的IP地址: 使用 request.META[‘REMOTE_ADDR’] 2. 使用中间件 ...

  9. MySQL数据库Innodb储存引擎----储存页的结构

    上一篇博客回顾: 1:数据库拥有众多的储存引擎,现在主要使用的是Inoodb,这个储存引擎有Compact,Redundant,Dynamic,Compressed四种行格式 2:Compact行格式 ...

  10. Coxph model Pvalue Select2

    4   1) Put summary(coxphobject) into a variable summcph <- summary(coxphobject) 2) examine it wit ...