调试网站
http://babeljs.io/repl/
扩展阅读:
# export、exports、modules.exports 和 require 、import 的一些常用方法和套路 http://www.cnblogs.com/CyLee/p/5836069.html
# es6学习笔记
https://github.com/dragon8github/es6-Study-Notes
(数组)扩展运算符使用
// demo 1 var a = (...args) => console.log(args) a(1, 2, 3, 4) // [ 1, 2, 3, 4 ] // demo 2 console.log(...[1, 2, 3, 4]); // 1 2 3 4 // demo 3 Math.max(...[1, 2, 3, 4, 5]) // 5 // demo 4 var arrl = [0, 1, 2]; var arr2 = [3, 4, 5]; arrl.push(...arr2); // [ 0, 1, 2, 3, 4, 5 ]
箭头函数与高阶函数
getters: { // ... getTodoById: state => id => state.todos.find(todo => todo.id === id) }
怎么会有两个箭头函数?语法错误吧?其实这就是一个函数返回另一个函数罢了。简化一下:
getters: { // ... getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } }
然后再还原为es5的代码
"use strict"; getters: { // ... getTodoById: (function (state) { return function (id) { return state.todos.find(function (todo) { return todo.id === id; }); }; }); }
类的基本操作
class UserService { constructor(UserName,UserPwd) { this._UserName = UserName; this._UserPwd = UserPwd; } get UserName(){return this._UserName} //获取属性,命名必须大写开头 set UserName(n){this._UserName = /^w{6,19}$/.test(n)?n:null} //设置属性,命名必须大写开头 get UserName(){return this._UserName} //获取属性,命名必须大写开头 set UserName(n){this._UserName = /^w{6,19}$/.test(n)?n:null} //设置属性,命名必须大写开头 getVersion() { console.log("1.0"); } } let user = new UserService('Lee','123456'); //user.getVersion(); // console.log(user.name,user.pwd); user.UserName = 'dragon8github'; console.log(user.UserName);
5、使用promise写法
http://es6.ruanyifeng.com/#docs/promise
仔细研究这几个demo就可以学会promise的用法了:
// demo 1: Promise的基本特性和使用 var fuck = new Promise((resolve, reject) => { resolve("123"); // 会激活.then的第一个参数函数. 请注意,resolve 和 reject 这两个函数只能选择一个执行 reject("456"); // 会激活.then的第二个参数函数 或者 .catch函数 }) fuck.then(data => { console.log(data); // => 123 当Promise执行第一个参数函数reject时会触发 }, err => { console.log(err); // => 456 当Promise执行第二个参数函数reject时会触发 或者Promise发生错误时会触发。 }) fuck.then(data => { console.log(data); // => 123 当Promise执行第一个参数函数reject时会触发 }).catch(err => { console.log(err); // => 456 当Promise执行第二个参数函数reject时会触发 或者Promise发生错误时会触发。 }) // demo 2: 在promise中return,是return 一个promise对象,所以可以无限的.then/.catch var fuck = new Promise(function(resolve, reject){ resolve("123"); // 会激活p.then的第一个参数函数, 注意,如果调用这个。这个函数就会停止执行,所以下一句代码没有效果 reject("456"); // 会激活p.then的第二个参数函数 或者 p.catch函数 }); fuck.then(data => { console.log(data); // => 123 return data + 1 }).then(data2 => { console.log(data2); // => 1231 }) // demo 3: promise自动会启动try catch 机制 使用catch或者then的第二个参数函数捕获 var fuck = new Promise((a, b) => { mdzz() // 根本没有mdzz这个函数,所以会报错,也可以使用 throw new Error('mdzz') 来触发报错 }) fuck.then(data => { //do someting... }).catch(err => { // 这里可以捕获到err。当然你可以什么都不写。这样程序就不报错了。 // 但正常情况下还是建议处理好err console.log(123) }) // 或者这样 fuck.then(data => { console.log(data); // => 123 当Promise执行第一个参数函数reject时会触发 }, err => { console.log(err); // => 456 当Promise执行第二个参数函数reject时会触发 或者Promise发生错误时会触发。 }) // demo 4: 如何共享参数 // 暂时没有方法。只能用全局变量.下面是代码片段: connect().then(db => { return (this.db = db).collection('users') }).then(docs => { return docs.insert({name: this.name, pwd: this.pwd, email: this.email}, {safe: true}) }).catch(err => { this.db && this.db.close(); throw new Error(err); }) demo5: 实现finally函数 Promise.prototype.finally = function (callback) { let P = this.constructor; return this.then( ret => P.resolve(callback()).then( () => ret), err => P.resolve(callback()).then( () => {throw new Error(err) }) ); };
封装一个promise的函数,希望继续返回Promise.
以下是我实战的代码片段,仅供参考。
var MongoClient = require('mongodb').MongoClient; var url = 'mongodb://localhost:27017/myproject';
// 如果我要使用fuck()之后继续执行.then,那么说明这个fuck要返回一个promise即可。 let fuck = () => { // 由于我知道MongoClient.xxxx()也返回一个promise,所以这里直接返回即可。 return MongoClient.connect(url, {}).then(db => db).catch(err => { throw new Error(err); }); } fuck().then(db => { console.log(db); db.close(); })
async + await + Promise
// 使用async 和 await 必须配合使用Promise // 在同一个代码段中,不可以同时使用resolve和reject。因为他们执行之后会return const f = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(123); // reject(321) }, 1000); }); }; // async返回的是一个promise。所以别妄想在这里就可以直接返回普通类型的值(如string/object/Boolean) // 事实上,在这里面我也可以用Promise的方式.then()来解析。感觉就是一个语法糖。 // 总之指的注意的是,在这个async返回的是一个promise对象 const testAsync = async () => { try { let a = await f(); // 如果使用await,则接受起其返回值 console.log(a) // 输出123 return a // 请注意,虽然上句输出的是123,但返回的时候,却是一个Promise对象哦 } catch (err) { alert(err) // 可以获取reject的值 } }; let a = testAsync() console.log(a) // 注意这是一个promise
补充:2017-11-28
async 更像是一个标记。 await 也必须在有async 标记的函数中才可以正常使用。目前粗浅的理解是这样,而且大多数遇到的场景也是这样。如果以后碰到再回来补充。
await 标记的函数必须是返回promise才可以正常使用获取,如果不是只能是undefined。以Fetch为例演示(省略了async的标记):
let myjson = await fetch(API_SERVER, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(form) }).then(data => { return data.json() })
Async + await 新理解
使用它们的目的是,优雅的,不嵌套,不回调的使用返回值。
但代价就是,它们必须是同个圈子里的,也就是同个函数里的,也就是同个async函数里的。然后被执行才可以。
describe('注册', () => { it('注册', done => { const Register = async () => { // 获取验证码 const data = await xdapi.wechat_SmsSend({TelNo: '13713332657', Type: '1'}).then(data=>data); if (data.Data) { return await xdapi.wechat_Register({ TelNo: '13713332657', // 账号 Password: '123456.a', // 密码 ValidateCode: data.Data, // 验证码 ExtensionTelNo: '13713332652', // 推荐手机号 Type: 'wechat_pulic' // 注册方式是微信 }).then(data => data) } else { return {ReturnMessage: '获取验证码失败' + data.ReturnMessage}; } } Register().then(data => { if (data.ReturnCode == 1) { console.log(data) done() } else { Toast('注册失败:' + data.ReturnMessage); } }) }) })
ES6 class setTimeout promise async/await 测试Demo
class Person { async getVersion () { return new Promise((resolve, reject) => { setTimeout(function () { resolve('1.0'); // reject('fail') }, 1000); }) } } const start = async () => { var p = new Person(); const data = await p.getVersion(); console.log(20180716090040, data); } start(); // 20180716090040 "1.0"
proxy 代理的实战运用
如果你返回的是函数,那就是拦截函数,如果是其它类型。就是算是拦截属性
// 结合getter 和 proxy 的特性实现php中的__GET魔术函数 var api = {} /** * @func * @desc Proxy使用示例 * @param {object} - 要代理的对象 * @param {object} - 相关的代理配置 */ var proxy = new Proxy(api, { get: function (target, key, receiver) { console.log('获取函数名', key) // return Reflect.get(target, key, receiver) return function (aa) { window.alert(aa + key) } } }) proxy.fuck('abc')
函数名用类似数组的形式定义
const mutations = { INCREMENT (state,amount) { state.count = state.count + amount } //Es2015的知识点 ["SET_INCREMENT"] (state,amount) { state.count = state.count + amount } }
用for of 代替所有的遍历方式。 对数组和对象都使用for of
数组就用for(let [index,ele] of [].entries()), 对象就用 for (let [key, val] of Object.entries(obj))
除了entries, 还有keys() values() 详情百度
var aa = {boj1: {name:"fuck", age:18 }, obj2: {name:"shit", age:19 }} # 对象遍历 for (let [index, ele] of Object.entries(aa)) { console.log(index, ele) } # 数组遍历 for (let [index, ele] of [1, 2, 3].entries()) { console.log(index, ele) }