ES6、ES7、ES8学习指南(一)类、模块化、箭头函数、函数参数默认值

版本 发布时间 新特性
ES5 2009年11月 扩展了Object、Array、Function的功能等
ES6 2015年6月 类、模块化、箭头函数、函数参数默认值等
ES7 2016年3月 includes,指数操作符
ES8 2017年6月 async/await,Object.values(),Object.entries(),String padding等

ES6的特性

1.类(class)

class Animal{
	//构造函数,实例化时被调用,不指定则有一个不带参数的默认构造函数。
	constructor(name,color){
		this.name = name;
		this.color = color;
	}
	//toString 是原型对象上的属性
	toString(){
		console.log('name:' + this.name + ',color:' + this.color);
	}
}

var animal = new Animal('dog','white');//实例化Aniaml
animal.toString();

console.log(animal.hasOwnProperty('name'));//true
console.log(animal.hasOwnProperty('toString'));//false
console.log(animal._proto_.hasOwnProperty('toString'));//true

class Cat extends Aniaml{
	constructor(action){
	//子类必须在constructor中指定super函数,否则在新建实例时会报错。
	//如果没有置顶constructor,默认带super函数的constructor将会被添加。
	super('cat','white');
	this.action = action;
	}
	toString(){
		console.log(super.toString());
	}
}

var cat = new Cat('catch');
cat.toString();

//实例cat时Cat和Animal的实例,和ES5完全一致。
console.log(cat instanceof Cat);//true
console.log(cat instanceof Animal);//true

2.模块化(Module)

ES5不支持原生的模块化,在ES6中模块作为重要的组成部分被添加进来。
模块功能主要由 export 和 import 组成。
每个模块有自己单独的作用域,模块之间的相互调用关系是通过export 来规定模块对外暴露的接口,通过import 来引用其它模块提供的接口。
同时还为模块创造了命名空间,防止函数的命名冲突。

导出(export)

ES6允许在一个模块中使用export来导出多个变量或函数

导出变量

//test.js
export var name = 'Rainbow';

心得:ES6还可以导出常量。export const sqrt = Math.sqrt;//导出常量

ES6将一个文件视为一个模块,上面的模块通过export向外输出了一个变量。一个模块也可以同时向外面输出多个变量。

//test.js
var name = 'Rainbow';
var age = '24';
export{name,age};

导出函数

//myModule.js
export function myModule(someArg){
   return someArg;
}

导入(import)

定义好模块的输出后就可以在另一个模块通过import引用

import {myModule} from 'myModule';//main.js
import {name,age} from 'test';//test.js

心得:一条import语句可以同时导入默认函数和其它变量。import defaultMethod, { otherMethod } from 'xxx.js' ;

3.箭头(Arrow)函数

箭头函数与包围它的代码共享同一个this,能帮你很好的解决this的指向问题。有经验的Javascript开发者都熟悉诸如var self = this;var that = this 这种引用外围this的模式。但借助=>,就不需要这种模式了。

箭头函数的结构

箭头函数的箭头=>之前:是一个空括号、单个的参数名、或用括号括起的多个参数名
箭头之后:可以是一个表达式(作为函数的返回值),或者是用花括号括起的函数体(需要自行通过return来返回值,否则返回的是undefined)

//箭头函数的例子
()=>1;
v=>v+1;
(a,b)=>a+b;
()=>{
	alert("foo");
}
e=>{
	if(e == 0){
		return 0;
	}
	return 1000/e;
}

不论是箭头函数还是bind,每次被执行都返回的是一个新的函数引用,因此如果你还需要函数的引用去做一些别的事情(譬如卸载监听器),那你必须自己保持这个引用。

卸载监听器时的陷阱

错误的做法

class PauseMenu extends React.Component{
	componentWillMount{
		AppStateIOS.addEventListener('change',this.onAppPaused.bind(this));
	}
	componentWillUnmount{
		AppStateIOS.removeEventListener('change',this.onAppPaused.bind(this));
	}
	onAppPaused(event){
	}
}

正确的做法

class PauseMenu extends React.Component{
	constructor(props){
		super(props);
		this._onAppPaused = this.onAppPaused.bind(this);//保存this,保证添加和移除监听器同一个this
	}
	componentWillMount{
		AppStateIOS.addEventListener('change',this._onAppPaused);
	}
	componentWillUnmount{
		AppStateIOS.removeEventListener('change',this._onAppPaused);
	}
	onAppPaused(event){
	}
}

除了上述做外,还可以:

class PauseMenu extends React.Component{
	componentWillMount(){
		AppStateIOS.addEventListener('change',this.onAppPaused);
	}
	componentWillUnmount(){
		AppStateIOS.removeEventListener('change',this.onAppPaused);
	}
	onAppPaused = (event) =>{
		//把函数直接作为一个arrow function的属性来定义,初始化的时候就绑定好了this指针
	}
}

4.函数参数默认值

ES6支持在定义函数时为其设置默认值

function foo(height = 50, color = 'red'){
	//...
}

不使用默认值时

function foo(height, color){
	var height = height || 50;
	var color = color || 'red';
}

这样写一般没问题,但当参数的布尔值为false时,就会有问题了。比如,我们这样调用foo函数

foo(0, "");

因为0的布尔值为false,这样的height的取值将是50.同理color的取值为‘red’。
所以说,函数参数默认值不仅能使代码简洁,同时能规避一些问题。

你可能感兴趣的:(ES6、ES7、ES8学习指南(一)类、模块化、箭头函数、函数参数默认值)