let const的起源
let const是es6提出的,用于声明变量的指令
为什么要引入let const
js只有全局作用域跟函数作用域,没有全局作用域,这样可能会带来一些问题,比如
内层变量会覆盖外层变量
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
用来计数的变量会变成全局变量
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
块级作用域是怎么实现的
function foo(){
var a = 1
let b = 2
{
let b = 3
var c = 4
let d = 5
console.log(a)
console.log(b)
}
console.log(b)
console.log(c)
console.log(d)
}
foo()
- 当我们执行代码的时候,首先会创建代码执行的上下文,通过var声明的变量,会被放在变量环境里,通过let声明的变量,会被放在词法环境
- 在函数的作用域内部,通过let声明的变量并没有放到词法环境中。
- 当函数执行到函数的块状作用域时,会将函数内部let声明的变量,放到词法环境一个单独的区域中,这时候这个区域的变量跟外层词法环境的变量互不干扰。
- 词法环境内部,是一个栈结构,底层放着的,是最外层let声明的变量,当执行到一个块状作用域时,遇到新let声明的变量,就会将该变量压入栈顶(函数执行上下文的工作原理),然后执行完再弹出,如此执行下去。
ps
- es6的块状作用域,必须声明在大括号内,如果没有,则默认没有块状作用域。
- const的不变,指的是引用地址不能改变,所以对于object对象其实可以发生修改的。
小例子
执行下面这段代码,会发生什么,是为什么?
// 第一种写法,报错
if (true) let x = 1;
// 第二种写法,不报错
if (true) {
let x = 1;
}