学习React过程中,发现无论是github上的Demo还是React相关文档,ES6语法都有大量的使用。如果不了解一些ES6语法,很难学习下去。如果转战ES6,系统学习战线又较长。所以把一些常用的ES6语法做一些总结,有助于读懂React,Redux的文档。特别提醒:一些细节学习还是需要仔细查阅文档。
可以通过这个在线工具写ES6代码:http://www.es6fiddle.net/
let&const
这两个关键字大家应该都有了解,主要是引入了块级作用域,不存在变量提升,不能重复定义等特性。const是用来定义常量的。
文档:http://es6.ruanyifeng.com/#do...
解构赋值
常规用法
let { x } = { x: 1,y: 2} let { PropTypes } = React
这是对象的解构赋值,等同于let PropTypes = React.PropTypes
(注意这里包含了两步:声明变量PropTypes&赋值为React.PropTypes)。
所以这样写也是OK的
let PropTypes { PropTypes } = React
可以同时写多变量,如
let { PropTypes,Component } = React
如果想定义的变量名和属性名不一样,可以这样写
let { x: x1 } = { x: 1,y: 2}
声明x1变量,并赋值为1。注意x是模式,不是变量也不会被赋值
除了对象,数组,字符串等都有解构赋值的用法。
看文档:http://es6.ruanyifeng.com/#do...
对象的拓展
属性的简洁表达方式
let x = '123' let obj = { x,y: '33' }//等同于 let obj = { x: x,y: '33'}
如上代码所示,ES6允许对象内只写属性名,不写属性值,属性值就等于改与属性名相等的变量值
方法名也可以简写
let User = { method() { //等同于method: function(){ //... } }
属性名表达式
let key = 'id' let obj = { [key]: '1010',//注意与 key: '1010' 的区别 ['use' + 'name' ]: 'x' }
把表达式写在[]
中,表达式的值作为字段名称。
注意属性名表达式与属性名简写不能同时使用。如下
let key = 'id' let id = '1010' let obj = { [key] }
ES6 Class
使用ES6语法来定义一个React组件
export class Counter extends React.Component { constructor(props) { super(props); this.state = {count: props.initialCount}; this.tick = this.tick.bind(this); } tick() { this.setState({count: this.state.count + 1}); } render() { return ( <div onClick={this.tick}> Clicks: {this.state.count} </div> ); } } Counter.propTypes = { initialCount: React.PropTypes.number }; Counter.defaultProps = { initialCount: 0 };
有几个注意点:
使用了ES6的继承语法,关键字extends
constructor
是构造函数,可以替代getInitialState
。constructor
内需要调用父类的构造函数即super(props)
,否则就会报错。因为子类没有自己的this
对象,需要从父类继承。所以有用到this
的语句需要写在super(props)
之后。
this.tick = this.tick.bind(this);
这里使用bind
来绑定执行的作用域(使用React.createClass是自动绑定的),也可在render中监听事件的地方写bind(this)
,如下:
<div onClick={this.tick.bind(this)}> Clicks: {this.state.count} </div>
不过官方文档建议是统一写在constructor
中,这样该方法就只需要绑定一次。
除了使用bind(this)
,还可以使用箭头函数
<div onClick={()=>this.tick()}> Clicks: {this.state.count} </div>
这里就体现了箭头函数的特性:
函数体内的
this
就是定义时的对象,而不是调用时所在的对象。也就是说箭头函数的this
指向是固定的,而普通函数是可变的。
箭头函数
ES6允许使用=>
来定义函数
let f = v => v + 2 //等同于 let f = function(v){ return v + 2 }
如果有多个参数
let f = (x,y) => x + y
函数体有多条语句,用大括号包起来
let f = (x,y) => { x = x + 1 y = y + 3 return x + y }
在总结ES6的class
语法时也提到:箭头函数的this对象就是定义时所在的this对象,与执行时所在的对象无关
还有一点可以帮助理解:箭头函数的this指向能保持不变,不是因为内部有绑定的机制,而是箭头函数没有自己的this,导致代码内的this就是外层代码块的this
看文档:http://es6.ruanyifeng.com/#do...箭头函数
export&import
export
用于输出模块对外的接口,import
用于导入其他模块提供的功能。
export let client = 'APP' //输出变量 export function mul(x,y){ //输出函数 return x + y } export class Toast(){} //输出类
也可以统一输出
//文件名 util.js let client = 'APP' //输出变量 function mul(x,y){ //输出函数 return x + y } export { client,mul }
对应的导入应该这样用:
//注意这里有大括号,并且名称和输出时保持一致 import { client,mul } from './util.js'
下面这样写也可以
import * as U from './util.js' U.client //使用
我们很常用还有export default
命令,用于输出默认的方法,变量或类
export default React.createClass({ // ... })
引入的时候就比较方便,可以随意指定名字
import Tab from 'tab' //注意这里没有大括号
文档:http://es6.ruanyifeng.com/#do...
对象的拓展运算符...
拓展运算符属于ES7的提案,但babel已经支持,在Redux的示例Demo中很常见。
拓展运算符可以用来合并两个对象
//state = { name: 'y' } return {...state,name: 'x',id: 101 } //返回 { name: 'x',id: 101}
有两个点:取出state对象的所有可遍历属性,拷贝到当前对象上;如果自定义的属性放后面,拓展运算符的同名属性值则会覆盖掉。
这中用法等同与Object.assgin
Object.assgin({},state,{ name: 'x',id: 101 })
使用拓展运算符需要安装transform-object-rest-spread
插件,然后在babel
中配置。配置如下:
test: /\.js$/,exclude: /node_modules/,loader: 'babel',query:{ presets: ['react','es2015'],plugins: ["transform-object-rest-spread"] }
文档:http://babeljs.io/docs/plugin...
http://es6.ruanyifeng.com/#do...对象的扩展运算符
推荐ES6教程:http://www.hubwiz.com/course/...