天天看点

JavaScript变量作用域和变量提升

在看别人代码时,发现一个问题,就是一个未在上面声明或者定义的变量,可以正常使用而且不报错,我双击变量名,编译器给我把同名的高亮之后,发现这个变量的定义是在使用的下方定义的,网上查询才得知这是JS变量的一个特性,叫做变量提升,下面,先从最熟知的开始去理解这个变量提升!!

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript变量提升学习</title>
</head>
<body>

<script>
var a = "HelloWorld!";
console.log(a);
</script>

</body>
</html>
           

这是一个基本的变量赋值打印的过程,控制台输出结果也是正常的“HelloWorld!”,我们再看下一个:

<!DOCTYPE html>
<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!’,但是结果却让我大错特错:

JavaScript变量作用域和变量提升

这里就出现了一个JS的语法特征:变量提升

在理解这个之前,先来理解一下JS变量作用域的问题:

变量作用域

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript变量提升学习</title>
</head>
<body>

<script>

var abc = ;
console.log(abc);

if(){
    var abc = ;
    console.log(abc);
}

console.log(abc);

</script>

</body>
</html>
           

猜猜输出结果会是多少:

1,2,1?

1,2,2?

运行结果:

JavaScript变量作用域和变量提升

学过C的都知道,局部变量在函数内定义后,在函数执行完毕就会立刻销毁,与外部同名的全局变量不会产生任何影响,是因为在C系语言有块级作用域,当进入到一个块时,就像if语句,在这个块级作用域中会声明新的变量,这些变量不会影响到外部作用域。但是JavaScript却不是这样。

在这段代码中,Firebug显示1,2,2。这是因为JavaScript是函数级作用域(function-level scope)。这和C系语言是完全不同的。块,就像if语句,并不会创建一个新的作用域。只有函数才会创建新的作用域。

想要解决变量因作用域而对程序的影响时:我们可以这样:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript变量提升学习</title>
</head>
<body>

<script>

function foo(){
    var abc = ;
    if(abc){
        (function(){
            var abc = ;
        }());
    }
    console.debug(abc);
}

</script>

</body>
</html>
           

输出abc时,早已经不存在了:

JavaScript变量作用域和变量提升

这样就消除了 变量作用域的困扰。

变量提升

定义三个变量:

(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;。防止出现意外。

继续阅读