let
let 用于声明变量,声明的变量只在其所在的代码快内有效(块级作用域)
- 使用
for 循环的计数器就很适合使用let命令
for 循环中函数内部的变量i 与循环变量i 不在同一个作用域,而是有各自单独的作用域。
const
const 声明一个只读常量。
const 声明的变量并不是变量的直不可以改变,而是变量指向的那个内存地址不得改动。
简单类型的数据: 值就保存在变量指向的内存地址中,所以只读
复合类型的数据:变量指向的内存地址保存的只是一个指针。
- 对象冻结
使用Object.freeze();
const foo = Object.freeze({});
// 常规模式下,下面一行不起作用;
// 严格模式时,该行会报错;
foo.prop = 123;
- 冻结对象以及其属性
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key , i) => {
if ( typeof obj[key] === 'object') {
constantize(obj[key]);
}
})
}
暂时性死区 - let 和 const
只要块级作用域内存在let命令,它所声明的变量就 “绑定”这个区域,不在受外部影响。
var tmp = 123;
if ( true ) {
tmp = 'abc'; //报错
let tmp;
}
// let 所声明的变量一定要在声明后使用,否则会报错。let绑定了这个区域。
- 在'暂时性死区'中 typeof 变得不安全
1.
typeof x; //报错
let x;
2. typeof y //undefined
// y没有被声明,所以不会报错。
不允许重复声明 - let 和 const
let不允许在相同作用域内重复声明同一个变量。
// 所以在函数内部不能重新声明参数
let 和const 与var的区别
- 作用域的不同
(var 声明的变量在全局的范围内有效 如果用var 声明变量i, 那么i在全局范围内只能有一个。) - 变量提升
- var 命令会发生"变量提升"现象,即变量可以在声明之前使用,值为undefined.
- let 所声明的变量一定要在声明后使用,否则会报错。
问题
- 为什么需要块级作用域?
- 内层变量可能会覆盖外层变量
var tmp = new Date();
function f () {
console.log(tmp);
if (false) {
var tmp = 'hello world'
}
}
f(); //undefined
// if 中的tmp变量发生了变量提升。
- 用来计数的循环变量泄漏为全局变量
for (var i = 0; i < 5; i++) {
console.log(i)
}
console.log(i) //5
- ES6声明变量的方法
var function let const import class - 顶层对象属性
- 浏览器环境中的顶层对象是window对象
- Node 环境中的顶层对象是global对象
- ES5中顶层对象的属性与全局变量的赋值是同一件事。
- ES6中var 和function声明的变量依旧是顶层对象的属性,其他几种声明方式则不属于顶层对象的属性。
var a = 1;
console.log(window.a) //1(Node中用global,或通用this)
let b= 2
console.log(window.b) // undefined
网友评论