JavaScript 中的变量提升
来源:互联网 发布:国外的域名需要备案吗 编辑:程序博客网 时间:2024/06/05 15:21
一、案发现场
先看一段简单的代码:
var v = 'Hello World';alert(v);
这个没有疑问,弹出“Hello World”。OK,我们继续。
我们再看一段Code:
var v = "Hello World";(function(){ alert(v);})()
经过运行后,我们发现,还是和我们预期的一样,弹出了“Hello World”。
好了,有意思的来了。接着看一段下面的代码:
var v = "Hello World";(function(){ alert(v); var v = 'I love you';})()
这里出现的结果就必要意外了 ——— undefined 。
为什么这样呢?其实,这里隐藏了一个陷阱 —— JavaScript中的变量提升(Hoisting)。
二、深度剖析
现在我来解释下提升是什么意思?顾名思义,就是把下面的东西提到上面。在JS中,就是把定义在后面的东西(变量或者函数)提升到前面中定义。
在解释提升之前,我们先来看一下JS中的作用域(scoping)问题。
对于JavaScript人员来说,scoping是最令人困惑的部分之一。JavaScript的scoping如此复杂的原因是它看上去非常像C系语言的成员。请看下面的C程序:
#include <stdio.h>int main(){ int x = 1; printf("%d",x); //1 if(1){ int x = 2; printf("%d",x); //2 } printf("%d\n",x); //1}
这段程序的输出是1,2,1。这是因为在C系语言有块级作用域,当进入一个块时,就像if语句,在这个块级作用域中会声明新的变量,这些变量不会影响到外部作用域。但JavaScript却不是这样。
在Firebug中试试下面的代码:
var x = 1;console.log(x);if(true){ var x = 2; console.log(x);}console.log(x);
在这段代码中,Firebug显示1,2,2。这是因为JavaScript是函数作用域。这和C系语言是完全不同的。块,就像if语句,并不会创建一个新的作用域。只有函数才会创建新的作用域。
怎么才能让它不影响外部作用域呢?幸运的是,因为JavaScript函数的灵活性,对于这个问题我们有了一个解决方案。如果你必须在函数中创建一个临时的作用域(立即执行函数,执行完变量销毁),请像下面这样做:
function foo(){ var x = 1; console.log(x); //1 if(x){ (function(){ var x = 2; console.log(x); //2 })(); } console.log(x); //1}
它使用在任何需要创建一个临时作用域的地方,不仅仅是某个块中。
2.1变量提升
变量提升,很简单,就是把变量提升提到函数的top的地方。需要说明的是,变量提升只是提升变量的声明,并不会把赋值也提升上来。
比如:
我们定义三个变量:
(function(){ var a = 'one'; var b = 'two'; var c = 'three';})()
它实际上是这个样子:
(function(){ var a,b,c; a = 'one'; b = 'two'; c = 'three';})()
这个时候就把变量提升了。
好,我们现在回到第一段code里面。为什么会报错呢?其实,根据上面变量提升及js的作用域(块级作用域)的分析,得知上面的代码真正变成了:
var v = 'Hello World';(function(){ var v; alert(v); v = 'I love you';})()
所以,才会提示说“undefined”。
从这里,我们也学习到,我们在写js 代码的时候,我们需要把变量放在块级作用域的顶端。防止出现意外。
2.2函数提升
函数提升是把整个函数都提到前面去。
在我们写js代码的时候,我们有2种写法,一种是函数表达式,另外一种是函数声明方式。我们需要重点注意的是,只有函数声明形式才能被提升。
函数声明方式提升【成功】
function myTest(){ foo(); function foo(){ alert('我来自foo'); }}myTest();
函数表达方式提升【失败】
function myTest(){ foo(); var foo = function foo(){ alert(我来自foo"); }}myTest();
- JavaScript 中的变量提升
- javascript中的变量提升和函数提升
- JavaScript中的变量提升详解
- 浅淡JavaScript中的变量提升
- JavaScript 中的变量和函数提升
- 【转】JavaScript 中的变量和函数提升
- javascript中的变量提升和函数提升详解
- javascript中的变量提升和函数声明提升
- javascript中的变量作用域以及变量提升详细介绍
- javascript变量声明提升
- javascript 变量/函数 提升
- javascript变量声明提升
- JavaScript变量提升示例
- JavaScript变量提升-Hoisting
- JavaScript变量声明提升
- Javascript变量提升解释
- JavaScript 变量声明提升
- Javascript变量提升(Hoisting)
- oracle创建全文检索--多列
- bttorrent命令脚本测试
- 具体的设计模式(一):创建型模式
- 商城--更新管理员信息
- php5.3.0 新增参数类型
- JavaScript 中的变量提升
- scrapy的spider
- utf8mb4与utf8的区别
- js报错总结
- 【数据库】数据库设计三大范式
- 重构
- Linux下DISPLAY环境变量的作用
- 检测到远端rexec服务正在运行中
- 探索 DDS 和 EDA 工具