ES6的简单赘述
ES6简介
ES6,全称ECMAScript 6.0,是JavaScript的下一个标准版本,2015年6月发版。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
就目前来说,浏览器的JavaScript是ES5版本,大多数高版本的浏览器也支持ES6,但只是实现了ES6的部分特性和功能。
ECMAScript 的背景
JavaScript是 大众所知道的语言名称,但这个语言名称是oracle公司注册的商标。所以,JavaScript的正式名称是ECMAScript。1996年11月,JavaScript的创造者网景公司将JS提交给国际化标准组织ECMA(European computer manufactures association,欧洲计算机制造联合会),希望这种语言能够成为国际标准,随后ECMA发不了规定浏览器脚本语言的标准,即ECMAScript。这也有利于这门语言的开放和中立。
ECMAScript 的发展历史
1997年ECMAScript 1.0诞生。
1998年6月ECMAScript 2.0诞生,包含一些小的改动,用于同步独立的ISO国际标准。
1999年12月ECMAScript 3.0诞生,它是一个巨大的成功,在业界得到了广泛的支持,它奠定了JS的基本语法,被其后版本完全继承。直到今天,我们刚开始接触的JS,其实就是3.0版本的语法。
2000年,ECMAScript 4.0开始酿造,这个版本最后没有通过,但是它的大部分内容被ECMAScript 6继承了。因此,ECMAScript 6制定的起点其实是2000年。
2008年7月,由于对于下一个版本应该包括哪些功能,各方分歧太大,争论过于激烈,ECMA开会决定,中止ECMAScript 4.0的开发,将其中涉及现有功能改善的一小部分,发布为ECMAScript 3.1.而将其他激进的设想扩大范围,放入以后的版本,由于会议的气氛,该版本的项目代号起名为Harmony(和谐)。会后不就,ECMAScript 3.1就改名为ECMAScript 5。
2009年12月,ECMAScript 5.0正式发布。Harmony项目则一分为二,一些较为可行的设想定名为JavaScript。next继续开发,后来演变成ECMAScript6;一些不是很成熟的设想,则被视为JavaScript.next.next,在更远的将来再考虑推出。
2011年,ECMAScript 5.1发布后开始制定6.0版本。
2013年,ECMAScript 6草案冻结,不再添加新功能,新的功能设想将被放到ECMAScript7。
2015年6月,ECMAScript 6正式通过,成为国际标准,正式名称为“ECMAScript 2015”(简称ES2015)。
2016年6月,小幅修订的“ECMAScript 2016”(简称ES2016或ES7)标准发布,相当于ES 6.1版,因为两者差异非常小(只新增了数组实例的includes方法和指数运算符),基本上是同一个标准。
新增功能
声明命令
1.let 命令
ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
基本用法
1)代码块内有效
let是在代码块内有效,var是在全局范围内有效
function f(){
let a =10;
var b =11;
}
console.log(b);//1
console.log(a);//a is not defined a没有定义
2)不能重复声明
let只能声明一次,var可以声明多次
let a = 1;
let a = 2;
var b = 3;
var b = 4;
console.log(a);//'a' has already been declared
console.log(b);//4
declared
for循环计数器很适合用let
for(var i=0; i<10;i++){
setTimeout(function(){
console.log(i);
})
}
//输出10个10
for(let j=0; j<10;j++){
setTimeout(function(){
console.log(j)
})
}
//输出0 1 2 3 4 5 6 7 8 9
//变量i是用var声明的,在全局范围内有效,所以全局中只有一个变量i,每次循环时,setTimeout定时器里面的i指的是全局变量i,而循环里的十个setTimeout是在循环结束之后才执行的,所以此时的i都是10
//变量j使用let声明的,当前的j只在本轮循环中有效,每次循环的j其实都是一个新的变量,所以setTimeout定时器里面的j其实是不同的变量,即最后输出0123456789.(若每次循环的变量j都是重新声明的,如何知道前一个循环的值?这是因为js引擎内部会记住前一个循环的值。)
3)不存在变量提升
let不存在变量提升,var会变量提升
console.log(a);//Cannot access 'a' before initialization
console.log(b);//undefined
let a = 1;
var b=2;
//变量b用var声明存在变量提升,所以当脚本开始运行时,b已经存在了,但是还没有赋值,所以会输出undefined
//变量a用let声明不存在变量提升,在声明变量a之前,a不存在,所以会报错
2.const命令
基本用法:
const声明一个只读变量,声明之后不允许改变。意味着一旦声明必须初始化,否则会报错。const的作用域和let命令相同:只在声明所在的块级作用域内有效。
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数组、字符串、布尔值),值就保存在变量指向的那个内存的地址,因此等同于常量。但对于复杂类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象生命为常量必须非常小心。
const.f1={};
f1.prop=123;
console.log(f1);//{prop:123}
f1={};//Assignment to constant variable.
暂时性死区:
var PI="a";
if (true) {
console.log(PI);//Cannot access 'PI' before initialization
const PI= "3.1415926";
}
//ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。
3.class命令
ES6提供了更接近传统语言的写法,引入了class(类)这个概念(类的数据类型就是函数,类本身就指向构造函数),作为对象的模板。通过class关键字,可以定义类。class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
基础用法
1)类定义
类表达式可以为匿名或命名。
//匿名类
let Example = class{
constructor(a){
this.a =a;
}
}
//命名类
let Example = class Example{
constructor(a){
this.a = a;
}
}
2)类声明
class Example{
constructor(a){
this.a = a;
}
}
注意:不可重复声明
class Example{};
class Example{};//Identifier 'Example' has already been declared
let Example1 = class{};
class Example1{};//Identifier 'Example1' has already been declared
注意要点
类定义不会被提升,这意味着,必须在访问前对类进行定义,否则就会报错。
类中方法不需要function关键字。
方法见不能加分号
3)类的主体
a.属性
prototype
ES6中,prototype仍旧存在,虽然可以直接在类中定义方法,但是其实方法还是定义在prototype上的。覆盖方法/初始化时添加方法:
Examp.prototype={}
Object.assign(Example.prototype,{})
静态属性
静态属性:class本身的属性,即直接定义在类内部的属性(Class.propname),不需要实例化。ES6中规定,class内部只有静态方法,没有静态属性。
class.Example{
//新提案
static a= 2;
}
//目前可行写法
Example.b= 2;
公共属性
class Example{}
Example.prototype.a =2;
实例属性
实例属性:定义在实例对象(this)上的属性
class Example{
a=2;
constructor(){
console.log(this.a)
}
}
name 属性
返回跟在class后的类名(存在时)
let Example1 =class Exam{
constructor(a){
this.a=a;
}
}
console.log(Example1.name);//Exam class后面有类名是Exam
let Example2 =class{
constructor (a){
this.a=a;
}
}
console.log(Example2.name);//Example2 class后面没有类名
b.方法
constructor 方法
constructor方法是类的默认方法,创建类的实例化对象时被调用
class Example{
constructor(){
console.log("我是constructor");
}
}
new Example();//我是constructor
返回对象
class Test{
constructor(){
//默认返回实例对象
}
}
console.log(new Test() instanceof Test);//true
class Example{
constructor(){
//指定返回对象
return new Test();
}
}
console.log(new Example() instanceof Example);//false
console.log(new Example() instanceof Test);//true
静态方法
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
class Example{
static sum(a,b){
console.log(a+b);
}
}
Example.sum(1,2);//3
原型方法
class Example{
sum(a,b){
console.log(a+b);
}
}
let exam = new Example();
exam.sum(1,2);//3
实例方法
class Example{
constructor(){
this.sum=(a,b)=>{
console.log(a+b);
}
}
}