首页 > 语言 > JavaScript > 正文

新手快速入门JavaScript装饰者模式与AOP

2024-05-06 15:37:33
字体:
来源:转载
供稿:网友

什么是装饰者模式

当我们拍了一张照片准备发朋友圈时,许多小伙伴会选择给照片加上滤镜。同一张照片、不同的滤镜组合起来就会有不同的体验。这里实际上就应用了装饰者模式:是通过滤镜装饰了照片。在不改变对象(照片)的情况下动态的为其添加功能(滤镜)。

需要注意的是:由于 JavaScript 语言动态的特性,我们很容易就能改变某个对象(JavaScript 中函数是一等公民)。但是我们要尽量避免直接改写某个函数,这会导致代码的可维护性、可扩展性变差,甚至会污染其他业务。

什么是 AOP

想必大家对"餐前洗手、饭后漱口"都不陌生。这句标语其实就是 AOP 在生活中的例子:吃饭这个动作相当于切点,我们可以在这个切点前、后插入其它如洗手等动作。

AOP(Aspect-Oriented Programming):面向切面编程,是对 OOP 的补充。利用AOP可以对业务逻辑的各个部分进行隔离,也可以隔离业务无关的功能比如日志上报、异常处理等,从而使得业务逻辑各部分之间的耦合度降低,提高业务无关的功能的复用性,也就提高了开发的效率。

在 JavaScript 中,我们可以通过装饰者模式来实现 AOP,但是两者并不是一个维度的概念。 AOP 是一种编程范式,而装饰者是一种设计模式。

ES3 下装饰者的实现

了解了装饰者模式和 AOP 的概念之后,我们写一段能够兼容 ES3 的代码来实现装饰者模式:

// 原函数var takePhoto =function(){console.log('拍照片');}// 定义 aop 函数var after=function( fn, afterfn ){ return function(){let res = fn.apply( this, arguments ); afterfn.apply( this, arguments );return res;}}// 装饰函数var addFilter=function(){console.log('加滤镜');}// 用装饰函数装饰原函数takePhoto=after(takePhoto,addFilter);takePhoto();

这样我们就实现了抽离拍照与滤镜逻辑,如果以后需要自动上传功能,也可以通过aop函数after来添加。

ES5 下装饰者的实现

在 ES5 中引入了Object.defineProperty,我们可以更方便的给对象添加属性:

let takePhoto = function () {console.log('拍照片');}// 给 takePhoto 添加属性 afterObject.defineProperty(takePhoto, 'after', {writable: true,value: function () {console.log('加滤镜');},});// 给 takePhoto 添加属性 beforeObject.defineProperty(takePhoto, 'before', {writable: true,value: function () {console.log('打开相机');},});// 包装方法let aop = function (fn) {return function () {fn.before()fn()fn.after()}}takePhoto = aop(takePhoto)takePhoto()

基于原型链和类的装饰者实现

我们知道,在 JavaScript 中,函数也好,类也好都有着自己的原型,通过原型链我们也能够很方便的动态扩展,以下是基于原型链的写法:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选