一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(二)
2021-02-07 17:32
946 查看
JavaScript 设计模式(二)
本篇文章是
JavaScript设计模式的第二篇文章,如果没有看过我上篇文章的读者,可以先看完 上篇文章 后再看这篇文章,当然两篇文章并没有过多的依赖性。
5. 代理模式
代理模式提供了对目标对象的另一种访问机制。
在
vue3还没出来之前,我猜过可能会使用
proxy取代
defineProperty,结果也被验证了,毕竟
proxy比
defineProperty支持更多的拦截机制,可以对数组的方法进行拦截。
const obj = {}; const proxyObj = new Proxy(obj, { set(target, prop, value, receiver) { console.log("set:", prop, "=", value); Reflect.set(target, prop, value, receiver); }, }); proxyObj.a = 1
上述代码是用一个拦截器
Proxy作代理,使得每次在改变属性的时候,都能打印相应的日记,实际上如果
set内部改成
render函数,就可以做到数据改变的时候,渲染页面了。
6. 迭代器模式
迭代器模式能让我们不用在意数据真实的存储结构,更好的获取数据。
下面是一个迭代器模式的例子。
实际上由于原生的
JavaScript不支持对象进入
for of循环,原因是因为对象没有一个关于迭代器的
Symbol属性。
如果要支持的话,可以用下面的做法。
function* gen(obj) { const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { const key = keys[i]; yield [key, obj[key]]; } return; } const obj = { a: 1, b: 2, c: 3, }; for (let [key, value] of gen(obj)) { console.log(key, value); } // or // obj[Symbol.iterator] = gen.bind(this, obj); // for (let [key, value] of obj) { // console.log(key, value); //}
Generator函数返回一个 迭代器用于迭代,而
for of循环利用的就是这个迭代器。
7. 装饰器模式
在
ES7语法提案中,尚未正式确定,因此主流浏览器都暂时不支持,但是有
babel啊,这个神奇的工具可以帮助我们将
esnext转化为浏览器可以执行的代码。
在
bebel的官网上可以转化
decorators
const mixins = (...prototype) => { return (target) => { Object.assign(target.prototype, ...prototype); } } const readonly = (target, name, descriptor) => { descriptor.writable = false; return descriptor; } const prototype = { eat() { console.log("huro eat!") } } @mixins(prototype) class Person { @readonly name() { console.log("huro!!") } } const huro = new Person(); huro.eat(); // huro!! // 56c 我想改掉 huro 这个名字 huro.name = () => { console.log("xxx"); } // 修改无效 huro.name() // huro!!
利用装饰器模式,可以简化代码开发,很重要的一点是,装饰器也可以很好的起到注释的作用。
8. 状态模式
实际上
Promise的实现中就用到了状态模式,当然也用到了观察者模式,关于
Promise原理这块,给出简单的实现。并不遵循
Promise/A+规范。
关于以下代码的一步一步实现,可以参考知乎的一篇文章 图解 Promise 实现原理(一)—— 基础实现
enum Status { Pending = "Pending", Resolved = "Fulfilled", Rejected = "Rejected", } type PromiseFnType = ( resolve: (data: any) => any, reject: (error: any) => any ) => any; interface Callback { onResolved: (data: any) => any; onRejected: (error: any) => any; resolve: (data: any) => any; reject: (error: any) => any; } class MyPromise { status: Status; value: any; callbacks: Callback[]; constructor(fn: PromiseFnType) { this.status = Status.Pending; this.callbacks = []; this.value = null; fn(this.resolve.bind(this), this.reject.bind(this)); 1044 } then(onResolved?: (data: any) => any, onRejected?: (error: any) => any) { return new MyPromise((resolve, reject) => { this.handle({ onResolved, onRejected, resolve, reject, }); }); } handle(callback: Callback) { const { onRejected, onResolved, reject, resolve } = callback; if (this.status === Status.Pending) { this.callbacks.push(callback); return; } if (this.status === Status.Rejected) { let error = this.value; if (onRejected) error = onRejected(error); reject(error); } if (this.status === Status.Resolved && onResolved) { let value = this.value; if (onResolved) value = onResolved(value); resolve(value); } } reject(error: any) { this.value = error; this.status = Status.Rejected; this.callbacks.forEach((cb) => { this.handle(cb); }); } resolve(value: any) { if (value instanceof MyPromise) { const then = value.then; then.call(value, this.resolve.bind(this), this.reject.bind(this)); return; } this.value = value; this.status = Status.Resolved; this.callbacks.forEach((cb) => { this.handle(cb); }); } } new MyPromise((resolve, reject) => { resolve(1); }) .then((data) => { return new MyPromise((resolve, reject) => { resolve(data * 2); }); }) .then((data) => { console.log(data); });
总结
JavaScript设计模式是程序设计中很重要的一个环节,在了解了各种设计模式之后,可以在遇到实际项目的时候,预先选择好一个好的设计模式用于开发,提高项目的可扩展性,也有助于我们理解源码。
相关文章推荐
- 一篇文章图文并茂地带你轻松学完 JavaScript 闭包
- javascript 设计模式 - 文章很长,请自备瓜子,水果和眼药水
- 转载一篇有趣的文章 -- 追MM与设计模式
- 前端攻略系列(三) - javascript 设计模式(文章很长,请自备瓜子,水果和眼药水)
- 关于对项目组组员的一篇转IRRLICHTgui设计模式文章的评论
- javascript 设计模式 - 文章很长,请自备瓜子,水果和眼药水javascript
- 初学设计模式(3)-----单例模式(在研究单例的线程安全问题时,发现一篇很全面的文章,直接转了)
- 打算从今天开始每天发一篇设计模式相关的文章
- [转载野猪的一篇文章] 设计模式--简单工厂模式在unity3d里面的使用
- Javascript学习-设计模式文章推荐
- 一篇关于设计模式的好文章
- javascript 设计模式 - 文章很长,请自备瓜子,水果和眼药水
- Java开发中的23种设计模式,很好的一篇文章
- 推荐一篇文章,感觉学完Iterator模式后应当读一读
- 设计模式之flyweight模式(带例子),这一篇文章讲解的比较透彻,发现网上其它的讲的都太抽象了。
- 0 Java实现 一篇文章说尽设计模式之六大原则
- 转载—javascript 设计模式 - 文章很长,请自备瓜子,水果和眼药水
- 深入理解JavaScript系列(38):设计模式之职责链模式
- 一篇文章轻松搞懂原型对象和原型链
- 深入理解javascript之设计模式