在看别人代码时,发现一个问题,就是一个未在上面声明或者定义的变量,可以正常使用而且不报错,我双击变量名,编译器给我把同名的高亮之后,发现这个变量的定义是在使用的下方定义的,网上查询才得知这是JS变量的一个特性,叫做变量提升,下面,先从最熟知的开始去理解这个变量提升!!
<html>
<head>
<meta charset="utf-8">
<title>JavaScript变量提升学习title>
head>
<body>
<script>
var a = "HelloWorld!";
console.log(a);
script>
body>
html>
这是一个基本的变量赋值打印的过程,控制台输出结果也是正常的“HelloWorld!”,我们再看下一个:
<html>
<head>
<meta charset="utf-8">
<title>JavaScript变量提升学习title>
head>
<body>
<script>
var a = "HelloWorld!";
(function(){
console.log(a);
var a = 'I love you';
})()
script>
body>
html>
我原先也觉得至少会输出一个 ‘HelloWorld!’,但是结果却让我大错特错:
这里就出现了一个JS的语法特征:变量提升
在理解这个之前,先来理解一下JS变量作用域的问题:
<html>
<head>
<meta charset="utf-8">
<title>JavaScript变量提升学习title>
head>
<body>
<script>
var abc = 1;
console.log(abc);
if(1){
var abc = 2;
console.log(abc);
}
console.log(abc);
script>
body>
html>
猜猜输出结果会是多少:
1,2,1?
1,2,2?
运行结果:
学过C的都知道,局部变量在函数内定义后,在函数执行完毕就会立刻销毁,与外部同名的全局变量不会产生任何影响,是因为在C系语言有块级作用域,当进入到一个块时,就像if语句,在这个块级作用域中会声明新的变量,这些变量不会影响到外部作用域。但是JavaScript却不是这样。
在这段代码中,Firebug显示1,2,2。这是因为JavaScript是函数级作用域(function-level scope)。这和C系语言是完全不同的。块,就像if语句,并不会创建一个新的作用域。只有函数才会创建新的作用域。
想要解决变量因作用域而对程序的影响时:我们可以这样:
<html>
<head>
<meta charset="utf-8">
<title>JavaScript变量提升学习title>
head>
<body>
<script>
function foo(){
var abc = 1;
if(abc){
(function(){
var abc = 2;
}());
}
console.debug(abc);
}
script>
body>
html>
输出abc时,早已经不存在了:
这样就消除了 变量作用域的困扰。
定义三个变量:
(function(){
var a = 'first';
var b = 'sconed';
var c = 'thierd';
})();
实际上它是这样的:
(function(){
var a,b,c;
a = 'first';
b = 'sconed';
c = 'thierd';
})();
这时候,就把变量提升了啊!
我们回到前面的第个段代码,为什么显示undefined?
通过上面的变量提升,我们可以把代码写成:
var a='Hello World';
(function(){
var a;
alert(a);
a='I love you';
})()
所以才会提示undefined。
从这里,我学习到,我们在写js 的时候,我们需要把变量放在块级作用域的顶端,比如上面所举的例子:var a,b,c;。防止出现意外。