ES6常用总结

新增的常用特性:


1、Let 和Const 2、模板字符串 3、对象属性缩写 4、箭头函数 5、新增的对象操作方法 6、解构赋值 7、函数的扩展——默认参数 8、Promises  9、Class 10、Modules

一、let和const


1.块级作用域,在块级作用域外访问不到;

2.无变量提升,先声明后使用,否则报错;

3.拥有暂时性死区,即使与全局变量同名,在块级作用域中仍访问不到let定义的全局同名变量。原因是如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量就会报错;即使是typeof操作符也会报错;

4.let和const定义的变量不会成为window的属性,而var和function的全局声明会自动绑定到window对象;

二、模板字符串


1.方便的拼接字符串以及插入变量;

如:`my name is ${某个变量}`;可写多行;

三、对象属性缩写


1.同名属性可以缩写:

let obj = {

name// 等同于name:name

}

四、箭头函数 


1.箭头函数简化了函数的书写方式,使得书写更加优雅;

2.箭头函数绑定了上下文的this,使得this指向符合预期,而不必使用 _this = this  或.bind(this)获得预期的this值

五、新增的对象操作方法 


1.Object.is() 解决=== 的两个问题;

ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0

Object.is(+0,-0) // false

Object.is(NaN,NaN) // true

2.Object.assign()

Object.assign(target,source1,source2);

(1)Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target);

(2)目标对象有同名属性会覆盖源对象;

(3)如果该参数不是对象,则会先转成对象,然后返回;

(4)如果undefined和null在target参数位置则报错,否则转换不了对象而跳过;

(5)Object.assign方法实行的是浅拷贝,而不是深拷贝;

常见用途:  

(1)为对象添加属性

(2)为对象添加方法

(3)克隆对象 Object.assign({},origin)

(4)合并多个对象 Object.assign(target,...sources)

(5)为属性指定默认值 Object.assign({},DEFAULTS,options) 

3.Object.getOwnPropertyDescriptors()

返回某个对象属性的描述对象(descriptor)

4.__proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()

__proto__调用的是Object.prototype.__proto__,无论从语义的角度,还是从兼容性的角度,都不要使用这个属性,而是使用下面的Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)

5.Object.keys(),Object.values(),Object.entries() 

ES5 引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。ES2017 引入了跟Object.keys配套的Object.values和Object.entries,作为遍历一个对象的补充手段,供for...of循环使用。

六、解构赋值     


ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring);只要等号两边的模式相同,左边的变量就会被赋予对应的值。

1.解构不成功,变量的值就等于undefined;

2.如果是数组结构,等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错;

3.解构赋值允许指定默认值。ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效;

4.对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值;

5.对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量;

6.对象的解构赋值可以取到继承的属性;

7.函数的参数也可以使用解构赋值

七、函数的扩展——默认参数  


1.ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

2.参数变量是默认声明的,所以不能用let或const再次声明。

3.使用参数默认值时,函数不能有同名参数。

4.参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。

5.与解构赋值默认值可以结合使用;

6.定义了默认值的参数,应该是函数的尾参数,如果不是,则需显式传入undefined,不可省略否则报错;

7.一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。

8.(1)ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中;(2)rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错   

八、Promises  


Promise 是异步编程的一种解决方案,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

1.Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功,也可叫resolved)和rejected(已失败);

2.状态不受外界影响,且一旦状态改变,就不会再变;

缺点:

1.无法取消Promise,一旦新建它就会立即执行,无法中途取消;

2.不设置回调函数,Promise内部抛出的错误,不会反应到外部;

3.当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成);

用法:

1.ES6 规定,Promise对象是一个构造函数,用来生成Promise实例;

2.Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供;

3.resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

4.reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去;

5.Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

6.then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。建议使用then().catch(),而不是两个回调函数;

7.Promise.prototype.then()同第6点;

8.Promise.prototype.catch() 这方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

9.Promise.prototype.finally() finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

10.Promise.all() 接受一个数组作为参数,数组里都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理;

例如:const p=Promise.all([p1,p2,p3]);

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数;

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

11.Promise.race()

const p=Promise.race([p1,p2,p3]);

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

12.Promise.resolve() 将现有对象转为 Promise 对象,有4条规则;

13.Promise.reject() Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

14.Promise.try() 不知道或者不想区分,函数f是同步函数还是异步操作,但是想用 Promise 来处理它。

应用: 


const preloadImage=function(path){

return new Promise(function(resolve,reject){

const image=new Image();

image.onload=resolve;

image.onerror=reject;

image.src=path;

})

};

九、class 


引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类;

ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;

functionPoint(x,y){this.x=x;this.y=y;}

Point.prototype.toString=function(){return'('+this.x+', '+this.y+')';};

等同于:

classPoint{

   constructor(x,y){this.x=x;this.y=y;}

   toString(){

        return'('+this.x+', '+this.y+')';

    }

}

1.类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式

2.类不存在变量提升(hoist),这一点与 ES5 完全不同

3.Class 可以通过extends关键字实现继承

4.子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象

5.ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。

十、modules 


在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。

ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。

1.ES6 的模块自动采用严格模式

2.export 命令

export var firstName='Michael';

或 var firstName='Michael'; export{firstName};

export function multiply(x,y){return x*y;};

export输出的变量就是本来的名字,但是可以使用as关键字重命名

export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系,而不能导出一个值,如export m;

export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。

export命令可以出现在模块的任何位置,只要处于模块顶层就可以。

3.import命令

import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块对外接口的名称相同;

可以使用as关键字,将输入的变量重命名;

import命令输入的变量都是只读的,因为它的本质是输入接口。也就是说,不允许在加载模块的脚本里面,改写接口;

import命令具有提升效果,会提升到整个模块的头部,首先执行;

import是静态执行,所以不能使用表达式和变量;

import语句会执行所加载的模块,多次重复执行同一句import语句,那么只会执行一次,而不会执行多次;

import可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面,import * as xxx from 'xxx';

4.export default 命令

export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字,故import的时候可以随意取名字;

export default也可以用来输出类。

5.export 与 import 的复合写法

如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起;

export{foo as myFoo} from 'my_module';// 接口改名 

6.import()动态加载

import命令能够接受什么参数,import()函数就能接受什么参数,两者区别主要是后者为动态加载;

(1)按需加载

(2)条件加载

(3)动态的模块路径

你可能感兴趣的:(ES6常用总结)