<html>
<meta charset="utf-8">
<script type"text/javaScript">
var t="1";
var s="2";
function scope(){
console.log(s);
console.log(t);
var s=3;
console.log(s);
}
scope();
//结果输出为 undefined 1 3
</script>
</html>
变量作用域为词法作用域,即作用域在定义时就确定下来。
全局变量:函数外声明的变量,称为全部变量
局部变量:函数内部使用var声明的变量,称为局部变量
<html>
<meta charset="utf-8">
<script type"text/javaScript">
function func1(){
var num = 1;
function func2(){
return num;
}
return func2;
}
var num = func1()();
console.log(num);
</script>
</html>
闭包:在函数内部,定义一个子函数,子函数可以访问父函数的私有变量。可以在子函数中进行操作,最后将子函数通过return返回
<html>
<meta charset="utf-8">
<body>
<ul>
<li>10</li>
<li>20</li>
<li>30</li>
<li>40</li>
<li>50</li>
</ul>
</body>
<script type"text/javaScript">
var lis = document.getElementsByTagName("li");
for(var i=0; i<lis.length;i++){
lis[i].onclick = function(){
alert(i);
}
}
</script>
</html>
这里不管click哪个li,结果都是5
代码从上自下,执行完毕后,li的onclick还没有触发,for循环已经转完!
而for循环没有自己的作用域!所以循环5次,用的是同一个全局变量i!也就是在for循环转完后,这个全局变量已经变成了5,那么在怎点li,点第几个都会是5。
解决方案:使用闭包
var lis = document.getElementsByTagName("li");
for(var i=0; i<lis.length;i++){
!function(i){
lis[i].onclick = function(){
alert(i);
}
}
}
使用let, 声明一个变量,该变量的范围限于声明它的块中
var lis = document.getElementsByTagName("li");
for(let i=0; i<lis.length;i++){
lis[i].onclick = function(){
alert(i);
}
}
let和var的区别
变量作用范围,表现不同
function scope(){
var varTest = 'test var OK.';
let letTest = 'test let OK.';
{
var varTest = 'varTest changed.';
let letTest = 'letTest changed.';
}
console.log(varTest); //输出"varTest changed.",内部"{}"中声明的varTest变量覆盖外部的letTest声明
console.log(letTest); //输出"test let OK.",内部"{}"中声明的letTest和外部的letTest不是同一个变量
}
scope();
let不能重复声明同一个变量
<script type"text/javaScript">
var t="1";
let s="2";
function scope(){
var varTest = 'test var OK.';
let letTest = 'test let OK.';
var varTest = 'varTest changed.';
let letTest = 'letTest changed.';
console.log(varTest); //输出"varTest changed.",内部"{}"中声明的varTest变量覆盖外部的letTest声明
console.log(letTest); //输出"test let OK.",内部"{}"中声明的letTest和外部的letTest不是同一个变量
}
scope();
</script>
对待未声明的变量,let表现为error