前言
工作中使用ES6开发项目已经很长时间了,趁现在不忙,将ES6的知识点梳理一遍。一为查漏补缺,二为加深记忆。
let
与const
命令
let
命令的特点
1.不存在变量提升:即必选先声明后使用,否则报错
2.只在代码块中有效
3.暂时性死区
4.不允许重复声明
1、不存在变量提示
在ES5中,使用var声明的变量,在脚本开始运行时,变量已经存在,只不过值为undefined。
console.log(v); //undefined
var v = 'exit';
而let声明的变量,必须先声明后使用,否则会报错。
console.log(v); //ReferenceError: v is not defined
let v = 1;
2、只在块级作用域中有效
在代码快中,let声明的变量,在该代码块之外是无法访问的。
{
let a = 1;
var b = 2;
}
console.log(a); // ReferenceError a is not defined
console.log(b); // 2
一个常用的let技巧是配合for循环,如下代码所示:
for(let i = 0; i<10; i++){}
console.log(i); // Reference is not defined
3、暂时性死区(temporal dead zone, TDZ)
ES6规定,如果一个作用域中存在let或const命令声明的变量,这个作用域针对这些变量形成了封闭作用域,必须在该作用域中先声明后使用。封闭作用域的意思是指,同样名字的全局变量,将在这里无效。如下代码所示,
// global
let a = 1;
{
console.log(a); // ReferenceError a is not defined
let a = 2;
console.log(a); // 2
}
下面是一个比较隐蔽的暂时性死区
function bar(x = y, y=2) {
// ES6的默认参数,也是相当于在用let声明了x与y一句, let x = y;
return x + y
}
bar(); //ReferenceError y is not defined
4、(同一作用域内)不允许重复声明
跟var有区别的是var可以对一个变量重复声明,但是在同一个作用域中,let重复声明同一个变量会导致错误。
let a;
let a; //SyntaxError:Identifier 'a' has already been declared
Q1: 块级作用域是如何定义的?
A1:
Q2: 为什么需要块级作用域?
A2:在ES5中只有全局作用域,与函数作用域(也就是内部作用域),但是这通常会导致两个问题:
1.内部变量可能会覆盖外部变量:
let tem = new Date();
function foo() {
// 变量提示导致tem被覆盖
console.log(tem);
if(false){
//即便这里不会执行,function作用域内变量会存在提升的情况
var tem = 2;
}
}
foo(); //输出undefined
2.用来计数的循环变量泄露为全局变量
for(var i =0; i< 10; i++){
}
console.log(i); // 10
块级作用域出现之前,经常使用IIFE来处理私有变量的问题,避免别的代码修改到某个变量。
而块级作用域的出现,实际上使得广泛应用的立即执行函数表达式IIFE不再需要了。
const
命令的特点
- 声明常量
- const 声明的常量是引用类型的值时,const保存的只是引用的地址,但是不能保证引用类型的值不能改变
const obj = {};
// 有效
obj.a = 1;
obj = {}; //error 不能将obj指向两个内存地址
顶层对象的属性与全局对象属性
ES6规定:1:var function关键字声明的全局变量,依旧是顶层对象的属性。2:let const class命令声明的全局变量,不属于顶层对象的属性。
也就是说从ES6开始,全局变量属性将逐步与顶层对象的属性脱钩。
// 全局作用域
var a = 1;
console.log(window.a); //1
let b = 2;
console.log(window.b); //undefined
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。