js中的变量提升(hoisting)
来看如下代码:
- 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)的更多相关文章
- js中的变量提升(Hoisting)
<script> function test(){ console.log(a); console.log(foo()); var a=1; function foo(){ return ...
- JS中的 变量提升
首先纠正下,文章标题里的 “变量提升” 名词是随大流叫法,“变量提升” 改为 “标识符提升” 更准确.因为变量一般指使用 var 声明的标识符,JS 里使用 function 声明的标识符也存在提升( ...
- js中的变量提升和函数提升
从上周开始,我所在的学习小组正式开始了angular的学习,angular是全面支持es6的,所以语法上和以前的angular有了很大的不同,比如变量声明时就抛弃了var,而选择了let和const: ...
- js函数、变量提升(hoisting)
其实我只是想复习下变量提升的,然后看到了函数提升,然后再看到了函数声明.函数表达式. 有必要怀着敬仰之心提及园子里的TOM大叔的解密命名函数表达式,不愧是大叔,好好地脑补了下基础知识. 在ECMASc ...
- js中的变量提升与函数提升
先看看一个简单的代码 var str='Hello World'; alert(str);//弹出 Hello World 再看一段代码: var v='Hello World'; (function ...
- js中的变量提升
var v='Hello World'; (function(){ alert(v); var v='I love you'; })() 会出现alert出来的是undefined,原因是因为在函数域 ...
- JavaScript中变量提升------Hoisting
原谅链接:http://www.cnblogs.com/damonlan/archive/2012/07/01/2553425.html 因为这个问题很是经典,而且容易出错,所以在介绍一次.哈哈.莫怪 ...
- js 中的变量声明提前总结
一.var 声明 ES6之前,js 中声明变量基本上用 var 关键字: 1.如果访问未声明的变量,会报错:ReferenceError 2.声明了未赋值,值为 undefined,跟前面的报错是两回 ...
- JS 会有变量提升和函数提升
JavaScript变量函数声明提升(Hoisting)是在 Javascript 中执行上下文工作方式的一种认识(也可以说是一种预编译),从字面意义上看,"变量提升"意味着变量和 ...
随机推荐
- 管道和FIFO 一
管道和FIFO 管道(pipe) 管道在Unix及Linux进程间通信是最基础的,很容易理解.管道就像一个自来水管,一端注入水,一端放出水,水只能在一个方向上流动,而不能双向流动.管道 ...
- Zabbix二次开发_01基础
最近有个想法:想做一个zabbix数据的二次呈现,所以来写一下Zabbix的api的内容. 先说下zabbix api的认证基础. Zabbix API简介 Zabbix API开始扮演着越来越重要的 ...
- linux下安装jdk7
查看linux系统是32位还是64位系统:uname --mi686 //表示是32位x86_64 // 表示是64位新建一个jdk的安装目录,我这里是在/usr/local/下新建了java目录,命 ...
- Hadoop(1.2.1)安装
背景知识: 1.数据分布存储,不是复制存储 2.数据不动,代码动,由于分布式存储,所以把代码移动到数据的地方计算. 3.数据如何分割,hadoop提供的分割文件的编程接口 安装: 1.安装JDK 1. ...
- SignalR + Mvc 4 web 应用程序
在上节中,我们已经初步对 SignalR 进行了了解,这一节我们将做一个SignalR Demon,具体的步骤如下: 1. 创建一个 mvc 4 web 应用程序,并选择 Basic 2. 创建一个 ...
- Eclipse变量名自动补全问题 自定义上屏按键为TAB
Eclipse空格等号等都可以上屏,这样有时候输入变量名再按空格就会自动补全,非常讨厌.那么怎么办呢? 1.首先你的Eclipse需要装有 Eclipse plug-in development en ...
- (4/24) webpack3.x快速搭建本地服务和实现热更新
写在前面: (1)为了防止版本兼容问题,此处的webpack版本与之前的一致为:webpack@3.6.0.同时这里我们安装的webpack-dev-server版本是2.9.7版本. (2)之前已经 ...
- C#_Markov_心得感想
来到实验室正好有一个月了,趁着端午假期稍微轻松一些,在大改程序体系之前,想将自己在这30天中工作之一Markov回顾一下,将从真实的写程序中学习到的知识.思想记录下来.希望能和大家积极讨论! 本文会以 ...
- mysql 解除安全模式
问题:rror Code: 1175. You are using safe update mode and you tried to update a table without a WHERE t ...
- SqlServer——触发器
一:触发器基本知识 1.首先必须明确以下几点: 触发器是一种特殊的存储过程,但没有接口(输入输出参数),在用户执行Inserted.Update.Deleted 等操作时被自动触发: 当触发的SQL ...