“This is the 10th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

Decorator mode

Suppose we have a function, slow(x), which returns the same result for the same x.

Function slow(x) {// Assuming there is a lot of calculation here //.... return x; }Copy the code

If this function is called frequently, we may want to cache (remember) the results to avoid spending extra time on recalculation.

Think about what you would do if you had to deal with this problem.

You could probably do this by adding a caching function to slow(), but there is a more elegant way to do this by creating a wrapper function with caching added to it. The function looks like this:

function cachingDecorator(func) { let cache = new Map(); Return function(x) {if (cache.has(x)) {return cache.get(x); } let result = func(x); Func cache.set(x, result); // Then cache the result (remember). }; }Copy the code

Now let’s implement it

In this example, there are two functions slow and cachingDecorator:

  • The cachingDecorator is a decorator: a special function that takes the slow function and changes its behavior to make it cacheable.

  • For the slow function, the wrapped slow function still performs the same action as before from the external code. It simply adds caching capabilities to its behavior.

In this way, by separating the cache from the main function code, not only can the caching function be implemented without changing the code of Slow itself, but the same function can be implemented by calling the Cache Decorator for any function.

call

We used the decorator pattern to cache the results of a function. Now suppose we have an object method

let worker = { someMethod() { return 1; }, slow(x) {console.log(' current this is ',this) // To execute, print the current this return x * this.somemethod (); }};Copy the code

We also want to implement caching to cache worker.slow results

As you can see, the normal call is ok, but after using the decorator wrapper, even though the method is called, the reference to this is changed, resulting in an error when trying to access this.somemethod.

So for this object method, our above cachingDecorator is no longer applicable, and we can use a special built-in method called func.call(context,… Args) (👉 portal), which allows a function to be called that explicitly sets this.

Now let’s rewrite the previous cachingDecorator function

function cachingDecorator(func) { let cache = new Map(); return function(x) { if (cache.has(x)) { return cache.get(x); } let result = func.call(this, x); Cache. set(x, result); return result; }; }Copy the code

At this point, you can see that the execution results are normal.

References:

Decorators and forwarding


🎨 [thumbs up] [concerns] don’t get lost, more front-end dry goods waiting for you to unlock

Phase to recommend

👉 front-end generation of TWO-DIMENSIONAL code and bar code complete solution

👉 can’t get out of 15 JavaScript array practical tips

👉 UI design for developers

👉 WebStorm practical configuration to improve productivity