在实现面向方面的编程时,我很困惑为什么 Dojo 必须有两个不同的方面库文件?
何时使用
dojo.aspect and dojox.lang.aspect ?
我以前从未听说dojox.lang.aspect
过,但根据git log
最新的提交日期到 2008 年。
dojox.lang.aspect
您可以在其作者 Eugene Lazutkin 的一篇文章中找到解释为什么存在: JavaScript 的 AOP 方面与 Dojo。
虽然在某些情况下它没有多大意义,但我们应该意识到 的主要作用
dojo.connect()
是处理 DOM 事件。[...]
总结一下:事件!= AOP。事件不能模拟 AOP 的方方面面,也不能用 AOP 代替事件。
所以 JavaScript 中的 AOP 听起来很简单!好吧,实际上有几个棘手的地方:
- 将每一个建议都作为一个函数来实现是很昂贵的。
- 通常迭代比递归调用更有效。
- 调用堆栈的大小是有限的。
- 如果我们有链式调用,就不可能重新排列它们。因此,如果我们想在中间删除一个建议,我们就不走运了。
- “around”通知将“吃掉”所有先前附加的“before”和“after”通知,改变它们的执行顺序。我们不能再保证“之前”通知在所有“周围”通知之前运行,等等。
- 通常为了从原始函数中解耦“环绕”通知,使用proceed()函数。调用它会导致调用 next-in-chain around advice 方法或原始方法。
- 我们的方面是一个对象,但在某些情况下我们希望它是一个静态对象,在其他情况下我们希望它是一个动态对象,创建时考虑到我们操作的对象的状态。
这些和其他一些问题在 dojox.lang.aspect 中得到解决(目前在主干中,将在 Dojo 1.2 中发布)。
从最新的 Dojo 1.7 开始,有一种区分事件和方面的强烈趋势,即在dojo/on
和之间dojo/aspect
(两者都是通过dojo.connect
之前实现的)。
从使用的角度来看,dojo/aspect 是 dojox/lang/aspect 的一个非常简化的版本。
使用dojo/aspect,您可以创建与命名函数相对应的方面(例如“xhr”类中的“get”方法),允许您在任何时候调用xhr.get 时创建一个before、after 或around 通知。
另一方面,(TMHO) 只有 dojox/lang/aspect 提供了足够的功能来玩 aop。它允许您使用正则表达式定义切入点,因此允许诸如“对任何名称以 get 开头的任何对象的任何函数执行环绕建议”...
您甚至可以传入将应用方面的函数名称或正则表达式的数组。
phusick 指出的博客文章提供了很好的例子。