let
定义
- 不存在变量提升
- 不存在变量提升typeOf也无法使用
- 只要在块级作用域内存在let命令,它所声明的变量就绑定在这个区域,不再受外部的影响。
- 命名不能重复
var c=1;
{
//console.log("before",c);//不存在变量提升
//console.log("typeOf",typeOf c);//typeOf
let c = 2;
//let c = 3;//命名不能重复
console.log('in',c);
}
console.log('out',c)
//in 2 //只要在块级作用域内存在let命令,它所声明的变量就绑定在这个区域,不再受外部的影响。
//out 1
let解决,闭包循环问题
document.body.innerHTML='<div id=div1>aaa</div><div id=div2>aaa</div><div id=div3>aaa</div>';
for(var i =1;i<4;i++){
//点击enter后 循环就结束了
document.getElementById('div'+i).
addEventListener('click',function(){
//当点击的时候,由于循环结束,i为4 所以就直接为4了。可以把闭包理解为回调函数。
alert(i)
//all are 4
})
};
//IIFE更改为:
document.body.innerHTML='<div id=div1>aaa</div><div id=div2>aaa</div><div id=div3>aaa</div>'
for(var i =1;i<4;i++){
console.log("i",i);
!function(i)
document.getElementById('div'+i).addEventListener('click',function(){
alert(i)
})
}(i);//直接创建一个立即执行的函数,循环的时候就调用,添加监听事件。
}
//let变量
document.body.innerHTML='<div id=div1>aaa</div><div id=div2>aaa</div><div id=div3>aaa</div>';
for(let i =1;i<4;i++){
document.getElementById('div'+i).
addEventListener('click',function(){
//读取作用域内的局部变量,同IIFE设置一个局部变量
alert(i)
})
};
块级作用域
//es5内层变量可能会覆盖外层变量
var tmp = 123;
function f() {
console.log(tmp);
if (false) {
//存在es5存在变量提升,所有回再次覆盖tmp;
var tmp = 'hello world';
}
}
f(); // undefined
//es6块级作用域
//ES5函数声明只能放在顶层作用域(window)和函数作用域中(闭包)。
//块作用域的函数声明,会提升到块级作用域的头部(得看浏览器实现情况)
var tmp = 123;
function f() {
console.log(tmp);
if (false) {
//let 仅在块内有效
function c(){
let tmp = 'hello world';
console.log(tmp)
}
}
}
f(); //123
const
定义
变量不会提升,不能重复定义;
const定义为常量(可查询,不可修改);
const基本数据类型不可以被修改,由于浅拷贝的原因,对象类型可以被修改。
const一声明就初始化,所有不可以分开定义。
//console.log(c);//变量不会被提升
const c = 1;
//c = 2;//基本数据类型不能被修改
//const c = 2; //不能重复定义
let d = {a:1};
const obj = d;
d = {a:2};//对象是地址的引用,所有const可以被拷贝
//const e;//一声明就初始化
const e = undefined;