在学习js中的装饰器之间,我们需要了解 AOP
(面向切面编程)编程思想。
AOP是一种可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的一种实现。
我们简单的举个例子来说明AOP。
这两个流程中, 验证用户
是共同的逻辑功能。那么在这儿,大家可能会想到抽取这个功能的代码,做成公共方法以便调用。
但是,做成公共方法调用的话,是侵入你的主流程里面的,非常的不雅观,也会混淆你的控制流程。在这儿, AOP
就有了用武之地。
在一整个流程中,将 验证用户
这个功能切出来。而其他地方需要使用,只要将东西切进去即可。
在前端JS编程中,我们可以采用Decorator装饰器,来实现AOP编程。大家也经常在React中,使用 React-Redux
的装饰器,来辅助我们建立 HOC
高阶函数,连接Redux的Store。
在进行实战之前,我们需要明确一个点就是: 装饰器对类的行为的改变,是代码编译时发生的,而不是在运行时。
class index { say () { console.log('say hello!') } }
我们先建立一个简单的类,这个类的作用,就是在执行 say()
的时候,打印出 say hello
。但是,在说话前,我们需要站起来。那怎么做?
class index { say () { console.log('站起来') console.log('say hello!') } }
在使用装饰器之前,我们需要侵入主流程,将代码写入。而现在,我们有了装饰器这一个工具。
class index { @up say () { console.log('say hello!') } } function up (target,name,descriptor) { const oldfn = target.descriptor.value target.descriptor.value = function () { console.log('站起来') oldfn.call(this) } return target }
以上代码可以通过 https://babeljs.io/repl编译后... 。通过编译后,我们执行以下代码:
var id = new index() id.say()
这个时候你会看到如下图:
成功的为 say
方法装饰了一个 站起来
。
至此,一个简单的装饰器范例已经完成。大家可以通过这种方式修改自己的代码,使自己的代码更加解耦。