primers

I’ve been busy reading the code for Megalo (there will be a series devoted to the source code of Megalo in the future, which is still interesting, you can look forward to it). Feel megalo, MPvue and other small programs cross-end framework, weeX cross-platform framework, the essence is similar, are fork a VUE to change, with the ability of Vue, in the platform specific API into their own.

Here’s a bit of code that I found interesting:

Vue.prototype._l = aop(Vue.prototype._l, {
    after: afterRenderList
  });
Copy the code

The code above extends the _L method on the Vue prototype using AOP, and then executes afterRenderList after the _L method has been executed.

So what is AOP?

What is the AOP

AOP(aspect-oriented Programming) : Section-oriented Programming, is a supplement to object-oriented Programming (OOP). Object-oriented is vertical programming, inheritance, encapsulation, and polymorphism, while aspect programming complements object-oriented.

In OOP, we focus on classes, while in AOP, we focus on facets.

For example, a form submission has a normal business submission process, but we want to add a form validation across the submission process. Or in a normal business, we would like to add some buried features horizontally, and then horizontally add the ability to collect error information at runtime, and verify whether there are operation permissions, etc., all of which are faceted programming.

In general, if you have a business scenario where you need to add some behavior from the outside to merge or modify the existing behavior, or separate the business logic code from the trivial code to separate complexity and so on, be sure to use this programming philosophy.

Typical applications of AOP include logging, performance monitoring, buried point reporting, exception handling and so on.

So how do you implement AOP in javascript?

ES3 is implemented by higher-order functions

What is a higher-order function?

Higher-order functions take one or more functions and return a function.

Higher-order functions that we often use are: once, debounce, Memoize, Fluent, etc

/ / function
var takePhoto =function(){
 console.log('Take a picture');
}
// Define an AOP function
var after=function( fn, afterfn ){
 return function(){
 let res = fn.apply( this.arguments );
 afterfn.apply( this.arguments );
 returnres; }}// Decorates the function
var addFilter=function(){
 console.log('Add filter');
}
// Decorate the original function with a decorator function
takePhoto=after(takePhoto,addFilter);
takePhoto();

Copy the code

Here’s another example of Fluent:

function fluent(fn) {
 return function(. args) {
 fn.apply(this, args)
 return this}}function Person() {}
Person.prototype.setName = fluent(function(first, last) {
 this.first = first
 this.last = last
})
Person.prototype.sayName = fluent(function() {
 console.log(this.first, this.last)
})
var person = new Person()
person
 .setName('Jone'.'Doe')
 .sayName()
 .setName('John'.'Doe')
 .sayName()
Copy the code

This is our standard way of dynamically extending properties noninvasively: extending the functionality needed to execute the original code. In fact, Megalo’s AOP also implements itself through higher-order functions.

          function aop(fn, options) {
            if (options === void 0) options = {};
            
            var before = options.before;
            var after = options.after;
            return function () {
              var args = [],
                  len = arguments.length;
              while (len--) {
                args[len] = arguments[len];
              }var self = this;
              
              if (before) {
                before.call.apply(before, [self, args].concat(args));
              }
              
              var ret = fn.call.apply(fn, [self].concat(args));
              
              if (after) {
                after.call.apply(after, [self, ret].concat(args, [ret]));
              }
              
              return ret;
            };
          }
Copy the code

The above AOP function extends the before and after methods to the source function fn.

ES5 decorator implementation

Object.defineproperty was introduced in ES5 to make it easier to add attributes to objects:

let takePhoto = function () {
 console.log('Take a picture');
}
// Add the attribute after to takePhoto
Object.defineProperty(takePhoto, 'after', {
 writable: true.value: function () {
 console.log('Add filter'); }});// Add the attribute before to takePhoto
Object.defineProperty(takePhoto, 'before', {
 writable: true.value: function () {
 console.log('Turn on the camera'); }});// Packing method
let aop = function (fn) {
 return function () {
 fn.before()
 fn()
 fn.after()
 }
}
takePhoto = aop(takePhoto)
takePhoto()
Copy the code

Decorator implementation based on prototype chains and classes


class Test {
 takePhoto() {
 console.log('photos'); }}// after AOP
function after(target, action, fn) {
 let old = target.prototype[action];
 if (old) {
 target.prototype[action] = function () {
 let self = this; fn.bind(self); fn(handle); }}}// Use AOP functions to decorate primitives
after(Test, 'takePhoto', () = > {console.log('Add a filter');
});
let t = new Test();
t.takePhoto();

Copy the code

Implement decorators using ES7 decorators

The Decorator proposal has been extensively revised and is not yet finalized, so I wonder if the syntax will change again.

Scenario: Performance report

A typical scenario is to record the performance data of an asynchronous request and report it:

Scenario: Exception handling

We can do simple exception handling to the original code without intrusive modifications

For example, window.onerror cannot catch asynchronous errors such as setTimeout, so someone would do something like this:

var _setTimeout = window.setTimeout
window.setTimeout = function(cb, timeout) {
 var args = Array.prototype.slice.call(arguments.2)
 return _setTimeout(function() {
 try{ cb(... args) }catch (error) {
 // Error is processed and reported to the server
 reportError(e)
 throw error
 }
 }, timeout)
}
Copy the code

Bytedance is hiring a lot of people

Bytes to beat (hangzhou) | Beijing | Shanghai a lot of hiring, welfare super salaries seconds kill BAT, not clock, every day to work in the afternoon tea, free snacks unlimited supply, free meals (I read the menu, Big gate crab, abalone, scallop, seafood, grilled fish fillet, beef, curry and spicy crayfish), free gym, touch bar, 15-inch top, new MBP, monthly rental allowance. This is really a lot of opportunities, the number of research and development after the expansion of N times, good technical atmosphere, cattle, less overtime, still hesitate what? Send your resume to the email below, now!

Just a small part of the JD link below, more welcome to add wechat ~

The front end of jd: job.toutiao.com/s/bJM4Anjob…

The back-end jd: job.toutiao.com/s/bJjjTsjob…

Jd: test job.toutiao.com/s/bJFv9bjob…

Jd: job.toutiao.com/s/bJBgV8job…

The front-end intern: job.toutiao.com/s/bJ6NjAjob…

The back-end intern: job.toutiao.com/s/bJrjrkjob…

Continue to recruit a large number of front-end, server, client, testing, products, internship recruitment are wide to

Resume send [email protected], it is suggested to add wechat Dujuncheng1, you can chat to chat about life, please indicate from nuggets and where to deliver the post