(1) 新的声明方式let
- 不属于顶层对象 window
//var -> variable
var a = 5; // 写var是在当前作用域下声明
console.log(a);
delete a;
console.log(a);
b = 6; // 不写 var 相当于在全局作用域下,给window声明一个属性
console.log(b);
delete b;
console.log(b); // 报错,因为b属于全局对象的一个属性,而a是一个变量
delete(是用来删除对象的属性)
// 如果用var来声明变量, 会一直被加到window对象中,
// 当声明了很多变量的时候,window这个对象会越来越大,最终导致了变量污染;
- 不允许重复声明
let a = 10;
let a = 20; // 报错!
- 不存在变量提升
console.log(a); // 存在变量提升,结果是undefined
var a = 5;
上述代码相当于:
var a;
console.log(a);
a = 5;
// -------------------------------------
console.log(b); // 不存在变量提升,结果报错
let b = 5;
- 暂时性死区
var a = 5;
if (true) {
a = 6;
let a;
}
// 报错,a在声明之前不能使用,因为在if语句中形成了一个封闭的空间
function foo(a = b, b = 2){
console.log(a, b); // 报错!因为代码是从左往右进行编译,是先有a再有b的
}
// 暂时性死区的本质是防止变量在声明之前被使用,能使代码更加安全
- 块级作用域
for (var i = 0; i < 3; i++){
console.log('循环内: ' + i); // 取到 0 1 2
}
console.log('循环外: ' + i); // 取到3
for (let i = 0; i < 3; i++){
console.log('循环内: ' + i); // 取到 0 1 2
}
console.log('循环外: ' + i); // 报错! 因为let具有块级作用域
// ------------------------------------------------
if (false) {
let a = 5;
}
console.log(a); // 报错
// ------------------------------------------------
if (true) let a = 10; // 报错! 用let声明变量哪怕只有一句代码,也需要加上双大括号
正确写法:
if (true) {
let a = 10;
}
- 测试题
for (var i = 0; i < 3; i++){
setTimeout(function(){
console.log(i); // 结果是3个3 why??
})
}
// 因为 setTimeout是等到主线程执行完成和到达时间以后才会执行
// 这涉及到了事件循环相关的知识
---------------------------------------------------
// 想要结果为 0 1 2,该怎么做?
// 使用闭包:
for (var i = 0; i < 3; i++){
(function(j){
setTimeout(function(j){
console.log(j); // 结果是 0 1 2
})
})(i)
}
// 用let
for (let i = 0; i < 3; i++){
setTimeout(function(){
console.log(i); // 结果是 0 1 2
})
}
(2) 新的声明方式const
- 不属于顶层对象window
// 在ES5中要声明一个常量:
Object.defineProperty(window, 'PI', {
value: 3.14,
writable: false
});
console.log(PI); // 3.14
PI = 5;
console.log(PI); // 3.14
// ----------------------------------------
// 在ES6中声明一个变量:
const a = 5;
a = 6; // 报错!
const a;
a = 5; // 报错! 必须在声明的时候就赋值
- 不允许重复声明
// 与 let 一致
const a = 10;
const b = 20; // 报错!
-
不存在变量提升
与 let 一致 -
暂时性死区
if (true) {
console.log(a);
const a = 10; // 报错
}
- 块级作用域
注意:如果被复杂数据类型时,可以对复杂数据类型中的属性进行修改
const obj = {
name: 'zhangsan',
age: 21
}
console.log(obj); // 结果是 {name: "zhangsan", age: 21}
obj.height = 1.88;
console.log(obj); // 不报错 {name: "zhangsan", age: 21, height: 1.88}
const arr = [1, 2, 3];
console.log(arr); // [1, 2, 3]
arr.push(4);
console.log(arr); // [1, 2, 3, 4]
网友评论