媒介
最近在回忆设想形式体式格局的学问,从新翻阅了《JavaScript形式》(个人觉得也算是一本小有名气的书了哈)一书,读时总有感想:期近将到来的ES6的大潮下,书中的很多形式的代码可用ES6的语法更加文雅简约的完成,而另一些形式,则已被ES6原生支撑,如模块形式(99页)。所以本身动手用ES6从新完成了一遍内里的设想形式,算是对其的稳固,也算是与人人一起来研讨讨论ES6语法的一些最好实践。
目次
(以下一切例子的原型均为《JavaScript形式》一书里“设想形式”章节中的示例)
代码repo地点,迎接star,迎接follow。
完成
单例形式
重要改变成运用了class的写法,使对象原型的写法更加清楚,更整齐:
js
'use strict'; let __instance = (function () { let instance; return (newInstance) => { if (newInstance) instance = newInstance; return instance; } }()); class Universe { constructor() { if (__instance()) return __instance(); //按本身需求实例化 this.foo = 'bar'; __instance(this); } } let u1 = new Universe(); let u2 = new Universe(); console.log(u1.foo); //'bar' console.log(u1 === u2); //true
迭代器形式
ES6原生供应的Iterator接口就是为这而生的啊,运用胖箭头函数写匿名函数(还顺带绑定了上下文,舒舒服服):
js
'use strict'; let agg = { data: [1, 2, 3, 4, 5], [Symbol.iterator](){ let index = 0; return { next: () => { if (index < this.data.length) return {value: this.data[index++], done: false}; return {value: undefined, done: true}; }, hasNext: () => index < this.data.length, rewind: () => index = 0, current: () => { index -= 1; if (index < this.data.length) return {value: this.data[index++], done: false}; return {value: undefined, done: true}; } } } }; let iter = agg[Symbol.iterator](); console.log(iter.next()); // { value: 1, done: false } console.log(iter.next()); // { value: 2, done: false } console.log(iter.current());// { value: 2, done: false } console.log(iter.hasNext());// true console.log(iter.rewind()); // rewind! console.log(iter.next()); // { value: 1, done: false } // for...of for (let ele of agg) { console.log(ele); }
工场形式
个人觉得变化比较不大的一个:
js
'use strict'; class CarMaker { constructor() { this.doors = 0; } drive() { console.log(`jaja, i have ${this.doors} doors`); } static factory(type) { return new CarMaker[type](); } } CarMaker.Compact = class Compact extends CarMaker { constructor() { super(); this.doors = 4; } }; CarMaker.factory('Compact').drive(); // 'jaja, i have 4 doors'
装潢者形式
for...of
轮回,新时代的for (var i = 0 ; i < arr.length ; i++)
? :
js
'use strict'; class Sale { constructor(price) { [this.decoratorsList, this.price] = [[], price]; } decorate(decorator) { if (!Sale[decorator]) throw new Error(`decorator not exist: ${decorator}`); this.decoratorsList.push(Sale[decorator]); } getPrice() { for (let decorator of this.decoratorsList) { this.price = decorator(this.price); } return this.price.toFixed(2); } static quebec(price) { return price + price * 7.5 / 100; } static fedtax(price) { return price + price * 5 / 100; } } let sale = new Sale(100); sale.decorate('fedtax'); sale.decorate('quebec'); console.log(sale.getPrice()); //112.88
战略形式
关于传统的键值对,运用Map来替代对象(数组)来构造,觉得带来得是更好的语义和更轻易的遍历:
js
'use strict'; let data = new Map([['first_name', 'Super'], ['last_name', 'Man'], ['age', 'unknown'], ['username', 'o_O']]); let config = new Map([['first_name', 'isNonEmpty'], ['age', 'isNumber'], ['username', 'isAlphaNum']]); class Checker { constructor(check, instructions) { [this.check, this.instructions] = [check, instructions]; } } class Validator { constructor(config) { [this.config, this.messages] = [config, []]; } validate(data) { for (let [k, v] of data.entries()) { let type = this.config.get(k); let checker = Validator[type]; if (!type) continue; if (!checker) throw new Error(`No handler to validate type ${type}`); let result = checker.check(v); if (!result) this.messages.push(checker.instructions + ` **${v}**`); } } hasError() { return this.messages.length !== 0; } } Validator.isNumber = new Checker((val) => !isNaN(val), 'the value can only be a valid number'); Validator.isNonEmpty = new Checker((val) => val !== "", 'the value can not be empty'); Validator.isAlphaNum = new Checker((val) => !/^a-z0-9/i.test(val), 'the value can not have special symbols'); let validator = new Validator(config); validator.validate(data); console.log(validator.messages.join('\n')); //the value can only be a valid number **unknown**
表面形式
这个几乎没啥好变的。。。:
js
'use strict'; let nextTick = (global.setImmediate == undefined) ? process.nextTick : global.setImmediate;
代办形式
应用extends
关键字来取得父类中的要领援用以及和父类雷同的类接口:
js
'use strict'; class Real { doSomething() { console.log('do something...'); } } class Proxy extends Real { constructor() { super(); } doSomething() { setTimeout(super.doSomething, 1000 * 3); } } new Proxy().doSomething(); //after 3s ,do something...
定阅/宣布形式
被Node原生的Events模块所支撑,一样连系默许参数,for…of遍历等特征,代码的削减以及可读性的增添都是可观的:
js
'use strict'; class Event { constructor() { this.subscribers = new Map([['any', []]]); } on(fn, type = 'any') { let subs = this.subscribers; if (!subs.get(type)) return subs.set(type, [fn]); subs.set(type, (subs.get(type).push(fn))); } emit(content, type = 'any') { for (let fn of this.subscribers.get(type)) { fn(content); } } } let event = new Event(); event.on((content) => console.log(`get published content: ${content}`), 'myEvent'); event.emit('jaja', 'myEvent'); //get published content: jaja
末了
以上一切代码都可经由过程Babel跑通,90%以上的代码可被当前版本的io.js(v2.0.2)跑通。