ECMAScript 是JavaScript的标准, JavaScript是ES的实现. ES6的正式名称是ES2015, 是ECMA标准的第6版
ES 6 新增 let 和const
对比原有变量声明的关键字 var
var : 变量, 可重复定义, 函数级作用域
let : 变量, 不可重复定义, 块级作用域
const : 常量, 不可重复定义, 块级作用域
let不可重复定义同名变量带来的好处是,在大型项目中,减少因为命名重复而导致的错误, 这样的错误往往很难排查. let是完全可以替代var的存在
var a = 1
var a = 2 //不报错
alert(a)
let b = 1
// let b = 2 //报错
alert(b)
const c = 1
// const c = 2 //报错
// c = 3 //报错
alert(c)
let对比var的另一个优势, 是let是块级作用域, 而var是函数级作用域. 在java等严格的语法中, 变量都是块作用域级别的, 这样的变量, 只在一个代码块内({}大括号内) 有效, 但是js中的var 确实函数级别作用域的, 一个变量的作用域会在整个函数中. 这带来了很多麻烦
看以下代码:
<body>
<input type="button" class="testBtn" value="0">
<input type="button" class="testBtn" value="1">
<input type="button" class="testBtn" value="2">
<script>
window.onload = function(){
let btns = document.getElementsByClassName("testBtn");
for(var i=0; i<btns.length; i++){
btns[i].onclick = function(){
alert(i)
}
}
</script>
</body>
为三个按钮添加点击事件, 点击按钮, 我们理想的情况是第一个按钮弹出0, 第二个按钮弹出1,第三个按钮弹出2, 运行结果是, 三个按钮点击弹出的都是3.
这是由于var 是函数级别作用域的变量, 他在整个函数中有效, 而不是在for循环的代码块中. 这样每次点击, 带出的i都是最后for循环完成后(结果是3)的结果.
为了修正整个作用域问题, 我们之前的做法是, 将for循环中加入新的函数, 用形参将i值传入, 每次for循环,创建一个函数, 以改变传入的i值的作用域
代码如下:
<body>
<input type="button" class="testBtn" value="0">
<input type="button" class="testBtn" value="1">
<input type="button" class="testBtn" value="2">
<script>
window.onload = function(){
let btns = document.getElementsByClassName("testBtn");
for(var i=0; i<btns.length; i++){
(function(i){
btns[i].onclick = function(){
alert(i)
}
})(i)
}
</script>
</body>
但是, 如果像java这样的严格语法的语言中, 存在块级作用域的变量, 就根本不会存在这样的问题, 我们可以let代替var来更简单的解决这个问题
<body>
<input type="button" class="testBtn" value="0">
<input type="button" class="testBtn" value="1">
<input type="button" class="testBtn" value="2">
<script>
window.onload = function(){
let btns = document.getElementsByClassName("testBtn");
for(let i=0; i<btns.length; i++){
btns[i].onclick = function(){
alert(i)
}
}
</script>
</body>
网友评论