var和let
var和let都是用于声明变量的,但两者有区别
什么是变量作用域
变量作用域指的是变量在什么范围内是可使用的
var存在的问题
以下面一个实例来展示。在这个示例中有五个button,我们希望点击任何一个button就会在控制台打印出我们点击的是第几个button。
<body>
<button>按钮一</button>
<button>按钮二</button>
<button>按钮三</button>
<button>按钮四</button>
<button>按钮五</button>
<script>
var btns = document.getElementsByTagName("button");
for(var i=0; i<btns.length; i++){
btns[i].addEventListener('click',function(){
console.log("我是第" + i + "个按钮");
})
}
</script>
</body>
我们发现无论点击第几个按钮,控制台打印出的都是第五个按钮。这是因为 va r在 if 语句和 for 语句中 没有块级作用域 引起的问题, var只有全局作用域和函数作用域。
在这个例子中可以看成是for语句执行了五次后(即 i = 5 时退出循环,i 相当于是一个全局变量),才会进行监听事件,所以控制台打印出的都是第五个按钮
用闭包解决var没有块级作用域的问题
函数有自己的作用域,闭包可以立即调用。在闭包中 i 相当于实参,index 相当于形参,形参和实参是互不影响的。
<body>
<button>按钮一</button>
<button>按钮二</button>
<button>按钮三</button>
<button>按钮四</button>
<button>按钮五</button>
<script>
//闭包可以解决问题(立即调用),因为函数有自己的作用域
for(var i=0; i<btns.length; i++){
(function(index){
btns[index].addEventListener('click',function(){
console.log("我是第" + (index+1) + "个按钮");
})
})(i)
}
</script>
</body>
用let解决var没有块级作用域的问题
ES6中的 let 是有 if 和 for 的块级作用域,效果等同于用闭包解决问题
<body>
<button>按钮一</button>
<button>按钮二</button>
<button>按钮三</button>
<button>按钮四</button>
<button>按钮五</button>
<script>
var btns = document.getElementsByTagName("button");
for(let i=0; i<btns.length; i++){
btns[i].addEventListener('click',function(){
console.log("我是第" + (i+1) + "个按钮"); //注意是i + 1
})
}
</script>
</body>
var和let的区别总结
(1)ES5中var是没有块级作用域的,ES6中的let是有块级作用域的
(2)ES5之前因为 if 和 for 都没有块级作用域的概念,所以在很多时候,我们必须借助于function的作用域(闭包)来解决应用外面变量的问题
(3)ES6中的 let 是有 if 和 for 的块级作用域
const
const修饰的标识符为常量,不可以再次赋值,保证数据的安全性
使用const建议和注意事项
建议: 在开发中,优先使用const,只有需要改变某一个标识符时才使用 let
注意:
(1)使用const修饰的标识符被赋值后不可以修改
//错误
const a = 20;
a = 10;
(2)定义时必须初始化赋值
//错误,没有赋值
const a;
(3)常量的含义是指向的对象不能修改,但是可以改变对象内部的属性
const obj = {
name:'yoyou',
age:18
}
obj = {} //错误, 指向新的对象
obj.age = 20; //正确