- let与块级作用域
如下代码分析:
for (var i = 0; i < 3; i++) {
for (var i = 0; i < 3; i++) {
console.log(i);
}
console.log('内层循环结束=' + i);
}
输出结果为:
但实际上才打印了3次,这是因为两个for循环内声明的变量是同一个i,内层循环的i会覆盖掉外层的i
此时,
let关键字能解决for循环计数器重名的问题
for (let i = 0; i < 3; i++) {
for (let i = 0; i < 3; i++) {
console.log(i);
}
console.log('内层循环结束' + i);
}
let声明的变量的作用域是块级的
用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效
如下代码分析:
var elements = [{}, {}, {}];
for (var i = 0; i < elements.length; i++) {
elements[i].onclick = function () {
console.log(i);
}
}
elements[2].onclick() //输出3
elements[2].onclick() 无论是打印哪个0、1、2,返回的结果都是3
这是由于循环结束之后,全局变量i都被累加到了3,所以打印出来的都是3
关于let关键字的坑解——跳转链接
(闭包概念)——可以关注一下面试题噢
如下代码分析:
for (let i = 0; i < 3; i++) {
let i = 'foo';
console.log(i); //打印了3次foo
}
结果表面for循环定义的i和循环内部定义的i是不一样的,就是说,他们不在同一个作用域当中
将上面的循环代码拆解开:(注意理解)
let i = 0;
if (i < 3) {
let i = 'foo';
console.log(i);
}
i++;
if (i < 3) {
let i = 'foo';
console.log(i);
}
i++;
if (i < 3) {
let i = 'foo';
console.log(i);
}
i++;
循环体内层定义的i是独立本身的作用域,外层是for循环本身的作用域
let关键字不会产生变量提升的问题
var会产生变量提升的问题,就是在定义这个变量之前调用并不会报错,如下:
console.log(i);
var i = 0;
所以之后出来的let纠正了这个问题(官方bug?)
在定义变量之前调用会报错,如下:
console.log(i);
let i = 0;//报错
//只能先定义这个变量
let i =0;
console.log(i);//0
- const关键字
const定义常量/恒量
也就是说,const关键字定义的变量不能被修改内存地址,并且只能在定义的时候赋予初始值,也就是写成同一句话,代码如下:
const i ='foo';
“不能被修改”的含义为,不能被修改的是内存地址,而非里面的某些值,比如:
const obj = {};
obj.name = 'lili';
这种情况下是可以的,改变obj对象里的属性和属性值,但并没有改变obj本身的内存地址。
但是如果接着:
obj = {};
这样的话会报错,因为这种赋值的操作相当于改变内存地址。
实际开发中推荐的写法:
尽量使用const,有可能要修改的变量用let,非必要不使用var