


Javascript aop (aspect-oriented programming) around analysis_javascript skills
Aop is also called aspect-oriented programming, in which "notification" is the specific implementation of aspects, which is divided into before (pre-notification), after (post-notification), and around (surround notification). Students who have used spring must be familiar with it. Very familiar, but in js, AOP is a seriously ignored technical point. However, using aop can effectively improve js code logic. For example, in front-end frameworks dojo and yui3, AOP is promoted to an internal mechanism of custom events, which can be seen everywhere in the source code. Thanks to this abstraction, Dojo's custom events are extremely powerful and flexible. The implementation of aop in dojo is in the dojo/aspect module. There are three main methods: before, after, and around. This article will lead you step by step to implement the around method. Subsequent articles will provide an in-depth analysis of the structural system of the dojo/aspect module.
To implement surround notification in js, the simplest and most thought-provoking way is to use callback
advice = function(originalFunc){ console.log("before function"); originalFunc(); console.log("after function"); } var obj = { foo: function(){ console.log('foo'); } } advice(obj.foo)
Result:
before function
foo
after function
Haha, it’s too simple. Can you go back to sleep? . . .
But, isn’t it a bit too rough? . . . The promised surroundings. . . . At least the next call to obj.foo should have this result, instead of a dry "foo"; for this we need to make some changes and use closures
advice = function(originalFunc){ return function() { console.log("before function"); originalFunc(); console.log("after function"); } } var obj = { foo: function(){ console.log(this.name); }, name: "obj" } obj.foo = advice(obj.foo) obj.foo()
Output:
before function
after function
It seems that the surround effect has been achieved, but where has the promised name gone? . . .
In the closure returned by advice, we also need to deal with scope issues
advice = function(originalFunc){ return function() { console.log("before function"); originalFunc(); console.log("after function"); } } var obj = { foo: function(){ console.log(this.name); }, name: "obj" } keepContext = function() { return obj['foo'].call(obj); } obj.foo = advice(keepContext);
It seems that the scope problem is solved by using call. Let’s run it and see:
Damn it, is this the legendary endless loop? . . .
It seems that we still need to make some changes and use an intermediate variable to eliminate the infinite loop
advice = function(originalFunc){ return function() { console.log("before function"); originalFunc(); console.log("after function"); } } var obj = { foo: function(){ console.log(this.name); }, name: "obj" } var exist = obj.foo; keepContext = function() { return exist.call(obj); } obj.foo = advice(keepContext); obj.foo();
Output:
before function
obj
after function
Haha, the world suddenly became a beautiful place. . . .
But does this bunch of code seem too low? Should we come up with some high-level abstractions? Well, I think so too
function around(obj, prop, advice){ var exist = obj[prop]; var advised = advice(function(){ return exist.call(obj, arguments); }); obj[prop] = advised; } advice = function(originalFunc){ return function() { console.log("before function"); originalFunc(); console.log("after function"); } } var obj = { foo: function(){ console.log(this.name); }, name: "obj" } around(obj, 'foo', advice); obj.foo();
The around method decouples the processing process from the specific object; as long as advice is written in the following format, the around effect can be achieved
advice = function(originalFunc){ return function() { //before originalFunc(); //after } }
Haha, you are so tall and cool in an instant, so cool. . . .
Then the question comes: What should I do if I accidentally call the around method one more time? . . . Forehead. . . . This is a question. Should we let around return a handle with a remove method to eliminate the binding, just like binding/removing events.
What remove means is that the next time the function is executed, it will no longer execute the corresponding around method, but only run the originalFunc method
function around(obj, prop, advice){ var exist = obj[prop]; var previous = function(){ return exist.call(obj, arguments); }; var advised = advice(previous); obj[prop] = advised; return { remove: function(){ obj[prop] = exist; advice = null; previous = null; exist = null; obj = null; } } } var count = 1; advice = function(originalFunc){ var current = count++; return function() { console.log("before function " + current); originalFunc(arguments); console.log("after function " + current); } } var obj = { foo: function(arg){ console.log(this.name + " and " + arg); }, name: "obj" } h1 = around(obj, 'foo', advice); h2 = around(obj, 'foo', advice); obj.foo(); h1.remove(); obj.foo(); h2.remove(); obj.foo();
Output:
before function 2 before function 1 obj and [object Arguments] after function 1 after function 2 obj and undefined before function 1
This. . Not only does it turn out to be a bit messy. . . Also reported an error. . . . Yes, it's bearable, but my uncle can't bear it. My uncle can't bear it, but my sister-in-law can't bear it!
Ah, closure. . . Please give me strength!
function around(obj, prop, advice){ var exist = obj[prop]; var previous = function(){ return exist.apply(obj, arguments); }; var advised = advice(previous); obj[prop] = function(){ //当调用remove后,advised为空 //利用闭包的作用域链中可以访问到advised跟previous变量,根据advised是否为空可以来决定调用谁 return advised ? advised.apply(obj, arguments) : previous.apply(obj, arguments); }; return { remove: function(){ //利用闭包的作用域链,在remove时将advised置空,这样执行过程中不会进入本次around //这几个不能删 //obj[prop] = exist; advised = null; advice = null; //previous = null; //exist = null; //obj = null; } } } var count = 1; advice = function(originalFunc){ var current = count++; return function() { console.log("before function " + current); originalFunc.apply(this, arguments); console.log("after function " + current); } } var obj = { foo: function(arg){ console.log(this.name + " and " + arg); }, name: "obj" } h1 = around(obj, 'foo', advice); h2 = around(obj, 'foo', advice); obj.foo('hello world'); h1.remove(); obj.foo('hello world'); h2.remove(); obj.foo('hello world');
Output:
before function 2 before function 1 obj and hello world after function 1 after function 2 before function 2 obj and hello world after function 2 obj and hello world
After the fight, call it a day!
The first time I stayed up all night to blog, I was also drunk. At two o'clock, I heard the fuck me next door. At four o'clock, I heard the crow of crows. There was also an unknown bird chirping. At five o'clock, there were a lot of people. Birds chirp. . . .
Reference article:
Use AOP to improve javascript code
AOP (aspect-oriented programming) and OOP (object-oriented programming) of yui3

C and JavaScript achieve interoperability through WebAssembly. 1) C code is compiled into WebAssembly module and introduced into JavaScript environment to enhance computing power. 2) In game development, C handles physics engines and graphics rendering, and JavaScript is responsible for game logic and user interface.

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

Zend Studio 13.0.1
Powerful PHP integrated development environment

SublimeText3 Linux new version
SublimeText3 Linux latest version

Atom editor mac version download
The most popular open source editor

SublimeText3 English version
Recommended: Win version, supports code prompts!