A Sneak peek to JavaScript AOP

综合技术 2018-05-25

As of last week, one of my co-workers has translated an article about ES6 Proxy. Shortly after I read that, I came up with an idea about JavaScript AOP (Aspect-Oriented Programming) . I talked to myself, Is there anyone who talk about it? How’s it going on in JavaScript world? Here I share what I found and explain how Proxy is related to AOP.

What is the Aspect-Oriented Programming anyway?

Actually, AOP is not the hot issue in JavaScript world at least for now. And I guess many of front-end developers are not familiar with the term. So let’s start with just “ AOP “, not the “ Javascript AOP “.

Have you tried searching for Aspect-Oriented Programming on Google? If you search for AOP and read them, soon you will find the term Cross-cutting Concern in all articles. The term may not be familiar with you. Think of logging which is a typical example. You can say “I should log at here, here and here too”. Regardless of the context of any class or function, it crosscuts all with a concern called logging.

Logging and Object-Oriented Programming Problem

Let’s look at an example below. I wrote a “hello world” AOP use case example. It is a simple code which gets book name from BookCollection by ISBN .

Now I want to log every time the function is called. And It’ll be better if it can handle the request from cache. Oh! and don’t forget to validate the ISBN as the value is from user input. Our work as a developer won’t finish simply. How will the code change if we add codes for caching, validating and so on?

I added logging from the initial implementation. And I guess some then().then().then() will be added. The code will be getting uglier and uglier. I won’t write an example for this :(. I am disappointed with my code, sitting in front of my laptop watching the code gets longer and uglier. I just wanted to get a book name. How come the work so complicate? Is the BookCollection class name right one? How can I fix this?

Find one reason to change and take everything else out of the class.

Reminding what uncle bob said , Let’s try to separate it into several classes.

Hm… It’s better. But is this really the best? Sure we can make it better with the power of OOP. But eventually, we will end up with creating long class names and complex inheritances.

So… does AOP make this code better?

A code below is written according to aspect.js library example.This article ain’t for explaining you aspect.js library. But I’ll use this as a demonstration. It is more familiar to Java developers than to Javascript developers. Even if this is not familiar to you, don’t worry. All you have to do is trust me that It logs after BookCollection.getNameByISBN . We will see how this work later this article. So just assume the code can be separated like this and move on.

The BookCollection class looks cleaner! It focuses on getting data. And logging resides on separated class. This time let’s do the same for the caching job too.

Yey! The irrelevant code in BookCollection has been removed completely and the role looks obvious. In this way, you can gradually add aspects . And no matter how much the aspects are added, BookCollection will remain focused on its own work.

And one more thing to say, note that the name pattern above can be applied to various classes and methods, given the expression /^get.*/ . Even if additional classes need to perform common operations, aspects can be applied to all of them without increasing the number of lines of code.

To explain again, we have separated logging, caching from original complex code. Those correspond to Cross-cutting Concern of Collection classes. At this point, if you are wondering if this code is really working this way, go to aspect.js and follow the example. And don’t forget Babel and Decorator plugin .


Decorators are being ready for the ES7 standard. Some of you may have already complained about the example above. Yes, the library depends on decorators that are not yet standard ( TC39 Notes, July 28 2016 , Implement new decorator proposal when finalized ). You can follow the example using the Babel Legacy Decorator plugin .(Do not hurry to apply it to a production project). Of course, there are some alternative libraries. But I choose aspect.js because it shows the AOP concept well. If you want to apply AOP to something right now, you can look up the meld or other libraries too.

How do I come up with Proxy?

It is hard to explain everything in this short article. I will just try to write only a short hint of how the “Proxy + Decorator = AOP” in Javascript. Do you remember that I mentioned Proxy is AOP’s related topic at the beginning of the article? Below is a code that mimics how the AOP Advice works by using a Proxy . ES6 Proxies and Classes are currently implemented in modern browsers, so copy and paste them into the browser as follows (no IE).

The above code creates a Proxy of the BookCollection prototype and executes the log only when a function of the given pattern is executed. If you are not familiar with Proxy , I recommend that you read the article “ ES6 Features — 10 Use Cases for Proxy ”. Now, let’s change the code by adding Decorators to bind the Logger and BookClass.

Don’t panic about @wove Decorators. @wove above is exactly the same code as the code below.

If you want to understand a little more about Descriptors, read Decorators , Decorators, and functions . Decorators are on the Stage2 Draft, and there are many discussions in the current standard. So, please consider that there is room for future changes. Back to the code above, I wrote it to show you how it works and it is not how aspect.js works. If you understand how it works so far, I think it would be enough to imagine how the code I introduced with AOP would work.

Final words

In the Java world, sometimes AOP is called “Black Magic”. In an interview with eWeek, James Gosling described AOP “Its fraught with all kinds of problems.”, “giving folks chainsaws without instructions.” I think this is because the AOP seems to crosscut the OOP rules of the Java world. If so, will it be true for the JavaScript world too? will JavaScript AOP be the black magic too? Given what we have, even if there is no AOP, and even if there are no tools like AspectJ, we may already be wielding a more outrageous laser blade. Considering what AspectJ needs to do to apply Aspect to Java code, the JavaScript code below is easy and natural (even if you think it is dangerous).

Considering the direction of the ES6 and ES7 standards, and the popularity of Typescript and etc, JavaScript is becoming more and more like an OOP, a tool we are familiar with. As time goes, I think that there will be more talk about AOP as a supplementary to OOP. Or maybe the nature of JavaScript does not need AOP. This article is at the introductory level, so if you have any ideas on this topic, please share your thoughts. I will try to think a little more and share my thoughts again if I have any other thoughts.


Originally published at medium.com on March 20, 2017.

KyuWoo Choi

FrontEnd Developer

Experienced Senior Frontend Developer. Experienced in OpenSource, FrontEnd, and Mobile. Skilled in JavaScript, Java, and C#. Please check my current works on GitHub.


Working with Dates in JavaScript, JSON, and Oracle... When I wrote a series of posts on creating JSON from relational data , I mentioned that dates could be tricky. That was a bit of an understateme...
弹窗插件 Layx v2.2.0 新增浮动窗口、窗口组合并等功能... Layx 一款熟悉但又不太一样的Web弹窗插件。 gzip压缩版仅 13.5kb,非常小巧。 更新日志 - 浮动窗口类型 - 浮动窗口options.floatTarget参数,floatTarget 用来设置吸附到那个元素上 - options.m...
或许你还没有真正的理解JS(浏览器环境)的Event Loop... 我们常说 JS 是单线程语言,但是别忘了常见的浏览器内核可都是多线程的,多个线程间会进行不断通讯,通常会有如下几个线程: GUI 渲染进程 JS 引擎线程 定时器线程 事件触发线程 异步 HTTP 请求线程 Microtask 与 Macrot...
给初学者:JavaScript 的常见注意点 上篇说了一些 JS 中数组操作的常见误区,这次来总结一下初学者常见的其他易错点。 写立即执行函数时前置 void 立即执行函数(IIFE)在 JS 非常常用,作用就是构造一个函数级的变量作用域。常见的写法如下: (function () { // code })(); 这样写可能...
浅谈 instanceof 和 typeof 的实现原理 typeof 一般被用于判断一个变量的类型,我们可以利用 typeof 来判断 number , string , object , boolean , function , undefined , symbol 这七种类型,这种判断能帮助我们搞定一些问题,比如在判断不是 object 类型...