let
1-1、let声明的变量只在let命令所在的代码块内有效
{
let a = 1;
var b = 2;
}
console.log( a ); // ReferenceError: a is not defined
console.log( b ); // 1 没有块级作用域,只有函数和全局作用域
1-2、let变量在for循环中只在循环体中有效;
for( let i = 0; i < 5; i++ ){
console.log( i ); 1、2、3、4
}
console.log( i ); // ReferenceError: i is not defined
1-3、let变量在for循环中每次循环的变量只在本轮循环中有效,每次循环都是一个新的变量;
var a = [];
for( let i = 0; i < 10; i++ ){
a[ i ] = function(){
console.log( i );
}
};
a[ 6 ](); // 6
1-4、for循环中,设置循环变量的部分是【父作用域】;循环体内部是单独的【子作用域】
for( let i = 0; i < 3; i++ ) ==> 父
{ ==> 子
let i = sun;
console.log( i ); // sun // sun // sun
}
2-1、let声明的变量不存在变量提升:let声明的变量一定要在声明后使用;如果在变量声明之前用到它,会抛出 【ReferenceError】的错误;
console.log( bar ); // ReferenceError
let bar = 1;
2-2、暂时性死区:
只要块级作用域内存在let命令,它所声明的变量就【绑定binding】这个区域,不在受外部影响; 如果区块中存在let和const命令,这个区块对这些命令声明的变量会形成【封闭作用域】。只要在声明变量之前 使用该变量,就会报错。
var tmp = 1;
if( true ){
tmp = 2; // ReferenceError
let tmp;
}
暂时性死区本质:只要进入当前作用域,所要使用的变量就已经存在,但是不可获取;
只有执行到声明变量的那一行代码出现,才可以在【声明变量的后面】获取和使用该变量。
let x = x; // x is not defined 声明之前不允许获取x的值
2-3、let不允许在【相同作用域内】重复声明同一个变量
function ()
{
let a = 10;
let a = 1; // 报错
}
function ( arg )
{
let arg; // 报错 形参【arg】是暂时性死区
}
function ( arg )
{
{
let arg; // 不报错【内层作用域不受外层作用域影响】
}
}
3-1、let的块级作用域: let声明变量绑定的作用域不受内层作用域的影响;内层作用域可以定义外层作用域的同名变量; 外层作用域无法读取内层作用域的变量;
3-2、do表达式:本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值;
{
let t = f();
t = t * t + 1;
}
在块级作用域之前加上【do】,使它变成【do表达式】,x会得到整个块级作用域的返回值
let x = do
{
let t = f();
t * t + 1;
}
const命令
1-1、const声明一个只读的常量,常量的值不能改变(Object除外);
const PI = 3.1415926;
console.log( PI ); // 3.1415926
PI = 10;
TypeError: Assingment to constant variable
1-2、const一旦声明常量,就必须立即初始化,不能留到以后赋值;
const foo;
// SyntaxError: Missing initializer in const declaration
1-3、const的作用域只在声明所在的块级作用域内有效;
if( true ) {
const MAX = 5;
}
console.log( MAX ); // Uncaught ReferenceError: MAX is not defined
1-4、const命令声明的常量不允许提升,同样存在暂时性死区,只能在声明后使用;
if( true ){
console.log( MAX ); // ReferenceError
const MAX = 5;
}
1-5、const常量不允许重复声明
const message = 'hello';
const message = 'world'; // 报错
const本质:const实际上保证的并不是变量的值不得变动,而是变量指向的那个【内存地址】不得改动。 对于简单数据类型的数据(数值、字符串、布尔值)而言,值就保存在变量指向的【内存地址】中,因此等同于常量。但对于复合类型的数据【对象和数组】而言,变量指向的是【内存地址中保存的一个指针】,(指向的是引用类型的地址)const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,完全不能控制;
块级作用域域函数声明
ES6引入了块级作用域,明确允许在块级作用域之中声明函数;
在块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用
ES6的块级作用域允许声明函数的规则只在使用大括号的情况下成立,如果没有使用大括号,就会报错;
ES6声明变量的6中方法
var、function、let、const、import、class