let和const命令
1. let命令
1.1基本用法
let命令和var命令相似,用于声明变量,但是所声明的变量只在let命令所在的代码块内有效。
{
let a = 11;
var b = 1;
}
a // ReferenceError: a is not defined
b // 1
for循环的计数器就很适合使用let命令
var a = [];
for (var i = 0 ; i < 10 ; i++){
a[i] = function () {
console.log(i);
};
}
a[6](); //10
var a = [];
for (let i = 0 ; i < 10 ; i++){
a[i] = function () {
console.log(i);
};
}
a[6](); //6
for循环特别之处:设置循环变量的那一部分是一个父作用域,循环体内是一个单独的作用域;
for (let i = 0 ; i < 5 ; i++) {
let i = 'abcd';
console.log(i);
}
// 打印4遍abcd
1.2不存在变量提升
变量提升:变量可以在声明前使用,值为undefined。
let命令改变了这种语法行为,他声明的变量一定在声明后使用,否则会报错。
// var
console.log(a);
var a = 3;
// 输出underfined
// let
console.log(a);
let a = 3;
// 报错ReferenceError 不存在变量提升
1.3暂时性死区
定义:无论使用let和const声明变量之前,该变量都是不可用的,这种语法称为暂时性死区(temporal dead zone)
var tmp = 123;
if(true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
暂时性死区也意味着typeof不再是一个百分之百安全的操作
typeof x; // ReferenceError
let x;
变量x使用let命令声明,所以在声明之前都属于x的死区,只要用到该变量就会报错‘
而如果一个变量根本没用被声明,使用typeof反而不会报错。
typeof temp // underfined
有些死区比较隐蔽,不太容易发现
function bar (x=y,y=2) {
return [x,y];
}
bar //报错
// 原因:参数x的值等于y,此时y没有声明属于死区
// 不会报错
function bar (x=2,y=x) {
return [x,y];
}
bar //[2,2]
1.4不允许重复声明
let不允许在相同作用域内重复声明同一个变量
// 报错
function () {
let a = 8;
var a = 7;
}
// 报错
function () {
let a = 8;
let a = 7;
}
// 报错
function (arg) {
let arg = 8;
}
// 不报错
function (arg) {
{
let arg = 7;
}
}
2.块级作用域
2.1为什么使用块级作用域?
第一,内层变量可能覆盖外层变量
var tmp = new Date();
function f() {
console.log(tmp);
if(){
var tmp = '哈哈哈';
}
}
f(); //underfined
第二,用来计数的循环变量泄露为全局变量
var s = 'hello';
for(var i= 0; i < s.length; i++){
console.log(s[i]);
}
console.log(i);//5
2.2ES6的块级作用域
function () {
let n = 5;
if(true) {
let n = 10;
}
console.log(n); //5
}
- 外层代码块不受内层代码块的影响
- 外层作用域无法读取内层作用域的变量
- 内层作用域可以定义外层作用域的同名变量
123