一、var
声明的变量会挂载在window上,而let
和const
声明的变量不会
var a = 521;
console.log(a,window.a); // 521 521
let b = 521;
console.log(b,window.b); // 521 undefined
const c = 521;
console.log(c,window.c); // 521 undefined
二、同一作用域下let
和const
不能声明同名变量,而var可以
let name = 'Tom';
let name = 'Jack';
console.log(name);
const name = 'Tom';
const name = 'Jack';
console.log(name);
var name = 'Tom';
var name = 'Jack';
console.log(name);
三、var
声明变量存在变量提升,let
和const
不存在变量提升
console.log(career); //undefined
var career = '学生';
console.log(career);
let career = '学生';
console.log(career);
const career = '学生';
四、let
和const
声明形成块作用域,只在代码块内有效
{
let girl = 'Lili';
}
console.log(girl);
换成var不报错:
{
var girl = 'Lili';
}
console.log(girl);
五、let
补充:不影响作用域链
{
let school = '尚硅谷';
function fn(){
console.log(school);
}
fn();
}
六、const
补充:声明的变量不可修改,而且必须赋初始值
const a;
const a = 10;
a = 20;
console.log(a);
七、let
示例
<div class="container">
<h2 class="page-header">点击切换颜色</h2>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<style>
.item {
width: 100px;
height: 50px;
border: solid 1px rgb(42, 156, 156);
float: left;
margin-right: 10px;
}
</style>
<script>
//获取div元素对象
let items = document.getElementsByClassName('item');
//遍历并绑定事件
for(let i = 0;i<items.length;i++){
items[i].onclick = function(){
//修改当前元素的背景颜色
// this.style.background = 'pink'; // 写法一
items[i].style.background = 'pink'; //写法二
}
}
</script>
我们可以看到用let
是可以实现点击效果的,但是如果改成 var
,再用第二种写法 items[i].style.background = 'pink';
就不可行了,大家可以试试。
这是因为全局变量i
出现了问题,改成 var
之后运行的代码其实是这样的,
{
var i = 0;
}
{
var i = 1;
}
{
var i = 2;
}
三次循环之后,i
做了个自增,此时i
为3,因为没有块级作用域,所以i
一直在全局中存在,可以打印一下i
的值,
for(var i = 0;i<items.length;i++){
items[i].onclick = function(){
//修改当前元素的背景颜色
//this.style.background = 'pink';
items[i].style.background = 'pink';
}
}
// {
// var i = 0;
// }
// {
// var i = 1;
// }
// {
// var i = 2;
// }
console.log(window.i);
故循环完成后,i
的值变为了 3 ,此时点击小方块就会执行点击事件,点击事件的函数块儿中找不到items[i]
就会去外层函数作用域里找,window下面的i
等于3,所以会出现问题。