一、var没有块级作用域,let有块级作用域
在了解var
和let
的区别之前,我们要知道什么是块级作用域,只有在真正了解了什么是块级作用域之后,才能真正了解var
和let
的区别。
1、块级作用域: 变量在什么范围内可用。
{
var name="vue";
console.log(name); //vue
}
console.log(name); //vue
在上面的例子中,大括号内部就是一个块级作用域,当在块级作用域外面调用name
时,是仍然可以访问到的,即块级作用域对于var
声明的变量并没有限制。但是在开发的过程中,我们并不希望在块级作用域外部可以访问到块级作用域内部的变量值,这往往会引起一些问题。
2、没有块级作用域引起的问题:if 块级
var func;
if(true){
var name="vue";
func=function (){
console.log(name)
}
}
var name="aaa"
func();
因为块级作用域对于var
声明的变量并没有限制,所以我们可以在函数外部改变函数内部声明的变量name
的值。打印出来的值将会是我们在函数外部定义的值name="aaa"
,而不是函数内部声明的值name="vue"
。在实际开发的过程中,一个函数可能会在多个地方调用,每次调用,都会改变函数内部变量的值,这很容易引起混乱。
3、没有块级作用域引起的问题:for 块级
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<script>
const btns=document.getElementsByTagName("button");
for(var i=0;i<btns.length;i++){
btns[i].addEventListener('click',function(){
console.log("第"+i+"个按钮被点击");
})
}
</script>
</body>
</html>
在控制台可看到,无论点击哪个按钮,显示的都是第3个按钮被点击,其原理和上述的例子雷同。当第 i
个按钮被点击时,执行对应的函数,但在真正开始用函数里面的 i
值时,其值已经被改变,此刻函数里面的 i
值已经被最后循环的 i
值所覆盖,所以会显示第3个按钮被点击。
ES6中,加入了let
,let
是有if
和for
的块级作用域。上面的例子中,将var改为let将会正确显示哪个按钮被点击。
<script>
const btns=document.getElementsByTagName("button");
for(var i=0;i<btns.length;i++){
btns[i].addEventListener('click',function(){
console.log("第"+i+"个按钮被点击");
})
}
</script>
因为let
有自己的作用域,上面的for
循环相当于有三个作用域,每个作用域里面的i
值将只在自己作用域内起作用,并不会受作用域之外变量的影响而改变其值,而var
声明时,相当于公用一个i
值。
二、const的使用
1、const
的主要作用是将某个变量修饰为常量,不可再次赋值。
2、什么时候使用const
哪?
顾名思义,当我们修饰的标识符不会被再次赋值时,可以使用const
来保证数据的安全性。
建议: 在ES6开发中,优先使用const
,只有需要改变某一个标识符的时候才使用let
。
3、const的注意
注意一:一旦给const
修饰的标识符赋值后,不能修改
const a = 20;
a = 10; //错误,不可以修改
注意二:在使用const
定义标识符时,必须进行赋值
const name; //错误,const修饰的标识符必须赋值
注意三:常量的含义是指向的对象不能修改,但是可以改变对象内部的属性。
const obj={
name:"vue",
age:18
}
obj.name="newVue",
obj.age=20 //正确,可以改变对象内部的属性