let

与 var 的区别,只作用在当前块级作用域内

1
2
3
4
5
6
7
8
for (let i = 0; i < 3; i++) {
};
console.log(i);//undefined

for (var i = 0; i < 3; i++) {
console.log(i);//0,1,2
};
console.log(i);//3

使用let或者const声明的变量 不能在被重新声明

1
2
3
4
5
6
7
var dad = '我是爸爸!';
console.log(dad);
var dad = '我才是爸爸!';
console.log(dad);

let son = '我是儿子';
let son = '我才是儿子';// Identifier 'son' has already been declared

不存在变量提升

1
2
3
4
5
// console.log(dad);
// var dad = '我是爸爸!';

// console.log(dad);
// let dad = '我是爸爸!';//Identifier 'dad' has already been declared

暂存死区

1
2
3
4
5
6
let a=1
(function(){
console.log(a);//Identifier 'dad' has already been declared
//此处往上为死区
let a=2;
}())

var 和 let 作用域有效问题

生成十个按钮 每个按点击的时候弹出1 - 10

1
2
3
4
5
6
7
8
9
10
11
var i = 0;
for (i = 1; i <= 10; i ++) {
(function(i) {//若没有函数自调用则会在最后弹出11,11,11,11
var btn = document.createElement('button');
btn.innerText = i;
btn.onclick = function() {
alert(i)
};
document.body.appendChild(btn);
})(i);
}

let就可以直接写

1
2
3
4
5
6
7
8
for (let i = 1; i <= 10; i ++) {
var btn = document.createElement('button');
btn.innerText = i;
btn.onclick = function() {
alert(i)
};
document.body.appendChild(btn);
}

const 声明常量

不可更改的量,在声明的同时必须被赋值
和let一样不能重复声明,不存在提升,只在当前块级作用域内有效

但是为引用类型的时候可以进行修改,因为地址是固定的,值却可以更改

Object.freeze(contsname);

在es6以前实现常量

  1. var BASE_COLOR="#000";//假装常量

2.

1
2
3
4
5
6
var CST={};
Object.defineProperty(CST,"BASE_NAME",{
value:"小明",
writable:false//CST对象中BASE_NAME为小明且不能被修改
})
Object.seal(CST);//CST禁止被扩展

常量封装递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Object.defineProperty(Object,"freezePolyfill",{
value:function(obj) {
for(var i in obj) {
if(obj.hasOwnProperty(i)){//检测有没有原型属性
if(typeof obj[i]=="object") {//属性中有没有对象,有的话再变成常量
Object.freezePolyfill(obj[i]);
}
Object.defineProperty(obj,i,{
writable:false
});
Object.seal(obj);
}
}
}
});
var xm={
age:14,
name:"xiaoming",
sex:{
val:"none"
}
}
Object.freezePolyfill(xm);