es6-let 和 const
1.let
1.1用法:类似var ,但是所声明的变量只在let命令所在的代码块内有效
{
let a = 10;
var b =1;
}
for 循环适合用 let
for( let i = 0; i<arr.length; i+=){ }
console.log( i ); // 这样会报错,i is not defined
对比var
var arr = [];
for( var i=0; i < 10; i++){
arr[i] = function(){
console.log(i);
};
}
arr[6](); // 10
let
var arr = [ ];
for( let i =0; i<10; i++){
arr[i] = function(){
console.log(i);
};
}
a[6](); // 6
1.2 TDZ
1.2.1 不存在变量提升,所以一定要先声明后使用
1.2.2暂时性死区 TDZ,简单说就是声明之前该变量都是不可用的
本质是进入当前作用域后,所使用的变量存在了但是不可获取,只有等到声明变量的哪一行代码出现,才可以获取和使用该变量
if( true ){
// TDZ开始
tmp = 'abc'; // 报错
console.log( tmp ); // 这两行都会报错
let tmp; // TDZ 结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
1.2.3 由于有TDZ 需要注意typeof
--没有let 之前,typeof 这个是永远不会有报错的情况的
--现在不一样了
typeof a; // 这样就会报错
typeof b; // 返回undefined,不会报错
let a;
1.2.4 还是说死区TDZ
function foo( x = y, y = 2 ){
return [x, y]; // 这样会报错,x = y的时候y没有声明
}
foo();
function foo( x = 2, y = x ){
return [x, y];
}
foo(); // [2, 2] 这是ok的
1.3不允许重复声明
以下都是报错的
function(){
let a = 10;
var a = 1;
}
function(){
let a = 1;
let a = 10;
}
function fn( arg ) {
let arg;
}
这样不报错
function fn( arg ) {
{
let arg; // 不报错
}
}
2. 块级作用域
2.1let就是新增了块级作用域
function f1(){
let n = 5;
if(true){
let n = 10;
}
console.log(n); // 5, 外层不会受里面的影响
}
2.2 允许任意的嵌套
{{{{{ let aaa = 123 }}}}}
2.3 外层不能读取内层
{{{{
{ let a = '123'}
console.log(a); // 报错
}}}}
内层作用域可以定义外层的同名变量
{{
let a = 'hello';
{let a = 'world'}
}}
取代立即执行函数
//IIFE
(function(){
var tmp = ...;
...
})()
// 块级作用域写法
{
let tmp = ...;
...
}
外层不能调用内部定义的函数
{
let a = 'secret';
function f(){
return a;
}
}
f(); // 会报错
下面这样写可以调用
let f;
{
let a = 'secret';
f = function(){
return a;
};
}
f(); // 'secret'
es5中的if for 循环之中是不能声明函数的
es6是ok的,但是,1.大括号不能省略,2.里面声明的函数外面是不可以用的
3. const命令
3.1 声明一个只读的变量,一旦声明,常亮的值就不能改变,所以他声明后必须立即初始化,而不能等到下面在赋值
'use strict' // 需要注意的是 use strict 模式会报错,常规不报错,但是也是无效的
const PI = 3.14;
PI // 3.14
PI = 3; // 报错
3.2 特点
const 的作用域和let 命令相同,只在块内有效;
同样没有声明提前,同样存在暂时性的死区,只能在后面使用
同样不可以重复声明
3.3 注意,对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址。
所以对象是可变的。
const foo = {};
foo.prop = 123;
foo.prop // 123 // 之后随便添加属性都ok
foo = {} // 但是改变指向的话报错
想改变的话,使用Object.freeze( { } );
3.4 es5中有两种声明变量的方法:var 和 function
es6 新增 let,const,import,class;一共六种
4.全局对象的属性
es6开始 var 和fucntion 声明的全局变量依旧是全局对象的属性;
let,const,class命令声明的全局的属性,不属于全局对象的属性,全局变量将逐步与全局对象属性脱钩