目录
一、简介
ES6,全称ECMAScript 6.0,是JavaScript的下一版本标准,2015.06发版。
ES6主要解决ES5的先天不足,比如JavaScript中没有类的概念,但是目前浏览器的JavaScript是ES5版本。大多数高版本的浏览器支持ES6。
1.1ECMAScript 的背景
JavaScript 是大家所了解的语言名称,但是这个语言名称是商标( Oracle 公司注册的商标)。因此,JavaScript 的正式名称是 ECMAScript 。1996年11月,JavaScript 的创造者网景公司将 JS 提交给国际化标准组织 ECMA(European computer manufactures association,欧洲计算机制造联合会),希望这种语言能够成为国际标准,随后 ECMA 发布了规定浏览器脚本语言的标准,即 ECMAScript。这也有利于这门语言的开放和中立。
1.2ECMAScript 的历史
ES6 是 ECMAScript 标准十余年来变动最大的一个版本,为其添加了许多新的语法特性。
- 1997 年 ECMAScript 1.0 诞生。
- 1998 年 6 月 ECMAScript 2.0 诞生,包含一些小的更改,用于同步独立的 ISO 国际标准。
- 1999 年 12 月 ECMAScript 3.0诞生,它是一个巨大的成功,在业界得到了广泛的支持,它奠定了 JS 的基本语法,被其后版本完全继承。直到今天,我们一开始学习 JS ,其实就是在学 3.0 版的语法。
- 2000 年的 ECMAScript 4.0 是当下 ES6 的前身,但由于这个版本太过激烈,对 ES 3 做了彻底升级,所以暂时被"和谐"了。
- 2009 年 12 月,ECMAScript 5.0 版正式发布。ECMA 专家组预计 ECMAScript 的第五个版本会在 2013 年中期到 2018 年作为主流的开发标准。2011年6月,ES 5.1 版发布,并且成为 ISO 国际标准。
- 2013 年,ES6 草案冻结,不再添加新的功能,新的功能将被放到 ES7 中;2015年6月, ES6 正式通过,成为国际标准。
二、新特性
1.新增关键字
1.1思考var关键字的缺点
变量提升问题:
我们在声明变量的唯一方式就是使用var关键字,但其实使用var关键字定义变量会出现以下情况
function getNumber(isNumber) {
if (isNumber) {
var num = "7";
} else {
var notNum = "not number!";
console.log(num);
}
}
getNumber(false);
我们在控制台可以看见以下报错:
明明在函数中定义了num变量,但返回的值是undefined
其实在JavaScript中有一个提升机制,无论在哪里使用var 关键字都会被提升到当前作用域的顶部。在运行getNumber函数时,实际上执行结构是下面内容:
function getNumber(isNumber) {
var num;
var notNum;
if (isNumber) {
num = "7";
} else {
notNum = "not number!";
console.log(num);
}
}
getNumber(false);
在开头时定义变量时,没有给num 变量赋值,并且getNumber传入的参数是false,导致if 语句没有执行,num没有赋值,所以控制台输出为 undefined
变量重复声明的问题:
使用var关键字声明的变量可以重复赋值,但在某些情况下回造成一些问题。例如以下:
function Sum(arrList) {
var sum = 0;
for (var i = 0; i < arrList.length; i++) {
var arr = arrList[i];
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
}
return sum;
}
var arr = [1, 2, 3, 4, 5];
document.write(Sum(arr));
在环境执行时,会出现环境卡死的情况。
因为在两层for 循环中我们使用同一变量i 进行赋值时,代码在执行过程中,第二层的 for 循环会覆盖外层变量 i 的值
非块作用域的问题:
使用var 关键字定义的变量只有两种作用域,全局作用域和函数作用域,两者都不是块结构,会造成变量提升。会出现以下问题:
function func() {
for (var i = 0; i < 5; i++) {}
document.write(i); // 5
}
func();
for循环中定义的i变量,被提升到了for语句之上,所以结束循环后,没有销毁i变量,我们能够在循环外获取它的值
1.2、认识let关键字
针对于以上的三个问题:
解决变量提升机制问题
ES6 为我们提供了let 关键字,它解决了变量提升到作用域顶部的问题。因为它的作用域是块级,没有提升机制。
function getNumber(isNumber) {
if (isNumber) {
let num = "7";
} else {
let notNum = "not number!";
console.log(num);
}
}
getNumber(false);
运行代码,控制台会出现报错信息如下:
ReferenceError是一个引用类型的错误,num is not defined 意思是num 变量并不出在
let 关键字声明的变量,其作用域是一个块,如果我们是在花括号{}里面声明变量,那么变量会陷入暂时性死区,也就是在声明之前,变量不可以被使用。
在上面代码中,我们的num 变量是放在if(){} 这个块中,并没有在else{}块中,所以会形成暂时性死区。
解决变量重复声明的问题
解决变量重复声明的问题
虽然let关键字声明的变量可以重新赋值,但与var 关键字有所不同,let 关键字不能在同一作用域内重新声明,而var 可以。
let i = 5;
let i = 6;
console.log(i);
可以看到控制台会报参数错误(SyntaxError)
解决非块级作用域的问题
前面我们已经说过使用 var
关键字定义变量,只有两种作用域,函数作用域和全局作用域,这两种都是非块级作用域。而 let
关键字定义的变量是块级作用域,就避免了变量提升。我们来看个例子。
function func() {
for (let i = 0; i < 5; i++) {}
console.log(i);
}
func();
控制台会出现错误
这是因为上面代码中的i 变量只存在于for循环这个块中,当循环结束,i变量就被销毁。
1.3、认识const关键字
在ES6 中,为我们提供了另一个关键字const 用于声明一个只读的常量。且一旦声明,常量的值就不能改变,如果尝试反复赋值,就会出现错误。例如:
const MaxAge = 100;
MaxAge = 10;
console.log(MaxAge);
既然是不可改变,那么我们在定义时,必须对它进行初始化,不然也会报错。
对于const 关键字定义的变量值,不可改变在于两个方面:
1.值类型
值类型是指变量直接存储的数据,例如:
const num = 20;
这里 num
变量就是值类型,我们使用的是 const
关键字来定义 num,故赋予变量 num
的值 20 是不可改变的。
2.引用类型
引用类型是指变量存储数据的引用,而数据放在数据堆中,比如,用const 声明一个数组。
const arr = ["一", "二", "三"];
如果你尝试去修改数组,同样会报错。
但是,使用const 关键字定义的引用类型还是可以通过数组下标去修改值
例如:
const arr = ["一", "二", "三"];
arr[0] = "四";
arr[1] = "五";
arr[2] = "六";
console.log(arr);
控制台显示如下:
变量arr 保存的是数组的引用类型,并不是数组中的值,只要引用的地址不发生改变就不会报错。
结语:
博主ES6专栏正在持续更新中。