1.let和var的区别
(1)var会存在变量提升的现象,let所声明的变量一定要在声明后使用,否则报错。
(2)let声明的变量只在它所在的代码块有效。var可以在代码块外进行调用。
代码如下:
{
var c = 1;
let g = 2;
console.log(g);//返回2
}
console.log(c);//返回1
console.log(b);//报错
var b = 1;
let a = 3;
console.log(a);//返回3
//块级作用域
var dates = new Date();
function f() {
console.log(dates);
if(false) {
var dates = "hello";
}
}
console.log(f()); //报错
function f1() {
let n = 5;
if(true) {
let n = 10;
}
console.log(n); // 5
}
(3)for循环存在父子作用域
for循环计数器:
代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,
从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。
另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
var arr = [];
for(let i = 0; i < 10; i++) {
arr[i] = function() {
console.log(i)//返回6
}
}
arr[6]();
代码中,变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。如果使用let,声明的变量仅在块级作用域内有效,最后输出的是 6。
var ar = [];
for(var i = 0; i < 10; i++) {
ar[i] = function() {
console.log(i);//输出10
}
}
ar[1]();
2.const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。