avatarGK

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

8604

Abstract

<span class="hljs-keyword">const</span> boundFn = fn.<span class="hljs-title function_">bind</span>(<span class="hljs-variable language_">this</span>); <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">defineProperty</span>(<span class="hljs-variable language_">this</span>, key, { <span class="hljs-attr">value</span>: boundFn, <span class="hljs-attr">configurable</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">writable</span>: <span class="hljs-literal">true</span>, }); <span class="hljs-keyword">return</span> boundFn; }, }; }

<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyComponent</span> { <span class="hljs-title function_">constructor</span>(<span class="hljs-params">props</span>) { <span class="hljs-variable language_">this</span>.<span class="hljs-property">props</span> = props; } @autobind <span class="hljs-title function_">handleClick</span>(<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">props</span>); } }</pre></div><p id="0013">In this example, the decorator is used to decorate the function so that it automatically binds this when called and returns a new function. This way, after instantiating , you don’t need to manually bind this when calling the function.<code>autobindhandleClickMyComponentthis.handleClick()</code></p><h1 id="3ffe">Logging</h1><p id="7a28">Decorators can be used to record logs, including printing information such as function calls, function execution times, etc.</p><div id="1a70"><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">log</span>(<span class="hljs-params">target, name, descriptor</span>) { <span class="hljs-keyword">const</span> originalMethod = descriptor.<span class="hljs-property">value</span>;

descriptor.<span class="hljs-property">value</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">...args</span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">Function <span class="hljs-subst">${name}</span> called with <span class="hljs-subst">${args}</span></span>); <span class="hljs-keyword">const</span> start = performance.<span class="hljs-title function_">now</span>(); <span class="hljs-keyword">const</span> result = originalMethod.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, args); <span class="hljs-keyword">const</span> duration = performance.<span class="hljs-title function_">now</span>() - start; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">Function <span class="hljs-subst">${name}</span> completed in <span class="hljs-subst">${duration}</span>ms</span>); <span class="hljs-keyword">return</span> result; }; <span class="hljs-keyword">return</span> descriptor } <span class="hljs-keyword">class</span> <span class="hljs-title class_">MyClass</span> { @log <span class="hljs-title function_">myMethod</span>(<span class="hljs-params">arg1, arg2</span>) { <span class="hljs-keyword">return</span> arg1 + arg2; } }

<span class="hljs-keyword">const</span> obj = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyClass</span>(); obj.<span class="hljs-title function_">myMethod</span>(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>); <span class="hljs-comment">// Output: </span> <span class="hljs-comment">// Function myMethod called with 1,2</span> <span class="hljs-comment">// Function myMethod completed in 0.013614237010165215ms</span></pre></div><h1 id="aff7">Authentication authentication</h1><p id="bbff">Decorators can also be used to check a user’s authentication status and permissions to prevent unauthorized users from accessing sensitive data or performing actions on a regular basis.</p><div id="be1a"><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">authorization</span>(<span class="hljs-params">target, name, descriptor</span>) { <span class="hljs-keyword">const</span> originalMethod = descriptor.<span class="hljs-property">value</span>;

descriptor.<span class="hljs-property">value</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">...args</span>) { <span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">isAuthenticated</span>()) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">'Access denied! Not authenticated'</span>); <span class="hljs-keyword">return</span>; } <span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">hasAccessTo</span>(name)) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">Access denied! User does not have permission to <span class="hljs-subst">${name}</span></span>); <span class="hljs-keyword">return</span>; } <span class="hljs-keyword">return</span> originalMethod.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, args); }; <span class="hljs-keyword">return</span> descriptor; }

<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyApi</span> { <span class="hljs-title function_">isAuthenticated</span>(<span class="hljs-params"></span>) { <span class="hljs-comment">// perform authentication check</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; } <span class="hljs-title function_">hasAccessTo</span>(<span class="hljs-params">endpoint</span>) { <span class="hljs-comment">// perform authorization check</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; } @authorization <span class="hljs-title function_">getUsers</span>(<span class="hljs-params"></span>) { <span class="hljs-comment">// return users data</span> } @authorization <span class="hljs-title function_">deleteUser</span>(<span class="hljs-params">id</span>) { <span class="hljs-comment">// delete user with id</span> } }</pre></div><h1 id="646e">Cache</h1><p id="3465">Decorators can also be used to cache the execution results of functions to avoid double evaluation.</p><div id="5257"><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">memoize</span>(<span class="hljs-params">target, name, descriptor</span>) { <span class="hljs-keyword">const</span> originalMethod = descriptor.<span class="hljs-property">value</span>; <span class="hljs-keyword">const</span> cache = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Map</span>();

descriptor.<span class="hljs-property">value</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">...args</span>) { <span class="hljs-keyword">const</span> cacheKey = args.<span class="hljs-title function_">toString</span>(); <span class="hljs-keyword">if</span> (cache.<span class="hljs-title function_">has</span>(cacheKey)) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">cache hit: <span class="hljs-subst">${cacheKey}</span></span>); <span class="hljs-keyword">return</span> cache.<span class="hljs-title function_">get</span>(cacheKey); } <span class="hljs-keyword">const</span> result = originalMethod.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, args); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">cache miss: <span class="hljs-subst">${cacheKey}</span></span>); cache.<span class="hljs-title function_">set</span>(cacheKey, result); <span class="hljs-keyword">return</span> result; }; <span class="hljs-keyword">return</span> descriptor; }

<span class="hljs-keyword">class

Options

</span> <span class="hljs-title class_">MyMath</span> { @memoize <span class="hljs-title function_">calculate</span>(<span class="hljs-params">num</span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'calculate called'</span>); <span class="hljs-keyword">return</span> num * <span class="hljs-number">2</span>; } }

<span class="hljs-keyword">const</span> math = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyMath</span>(); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(math.<span class="hljs-title function_">calculate</span>(<span class="hljs-number">10</span>)); <span class="hljs-comment">// Output: </span> <span class="hljs-comment">// calculate called</span> <span class="hljs-comment">// cache miss: 10</span> <span class="hljs-comment">// 20</span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(math.<span class="hljs-title function_">calculate</span>(<span class="hljs-number">10</span>)); <span class="hljs-comment">// Output: </span> <span class="hljs-comment">// cache hit: 10</span> <span class="hljs-comment">// 20</span></pre></div><h1 id="57d9">Aspect-oriented programming</h1><p id="0d61">Decorators can be used to implement facet-oriented programming, that is, to add functionality at runtime without modifying the original code.</p><div id="bc4d"><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">validate</span>(<span class="hljs-params">target, name, descriptor</span>) { <span class="hljs-keyword">const</span> originalMethod = descriptor.<span class="hljs-property">value</span>;

descriptor.<span class="hljs-property">value</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">...args</span>) { <span class="hljs-keyword">const</span> isValid = args.<span class="hljs-title function_">every</span>(<span class="hljs-function"><span class="hljs-params">arg</span> =></span> <span class="hljs-keyword">typeof</span> arg === <span class="hljs-string">'string'</span> && arg.<span class="hljs-property">length</span> > <span class="hljs-number">0</span>); <span class="hljs-keyword">if</span> (!isValid) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">'Invalid arguments'</span>); <span class="hljs-keyword">return</span>; } <span class="hljs-keyword">return</span> originalMethod.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, args); }; <span class="hljs-keyword">return</span> descriptor; }

<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyForm</span> { @validate <span class="hljs-title function_">submit</span>(<span class="hljs-params">name, email, message</span>) { <span class="hljs-comment">// submit the form</span> } }

<span class="hljs-keyword">const</span> form = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyForm</span>(); form.<span class="hljs-title function_">submit</span>(<span class="hljs-string">''</span>, <span class="hljs-string">'[email protected]'</span>, <span class="hljs-string">'Hello world'</span>); <span class="hljs-comment">// Output: Invalid arguments</span></pre></div><h1 id="c8da">Reversible decorators</h1><p id="5322">Decorators can also be applied in reversible scenes, for example, you can add a reversible decorator to modify function behavior.</p><div id="b868"><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">reverse</span>(<span class="hljs-params">target, name, descriptor</span>) { <span class="hljs-keyword">const</span> originalMethod = descriptor.<span class="hljs-property">value</span>;

descriptor.<span class="hljs-property">value</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">...args</span>) { args.<span class="hljs-title function_">reverse</span>(); <span class="hljs-keyword">return</span> originalMethod.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, args); }; <span class="hljs-keyword">return</span> descriptor; } <span class="hljs-keyword">class</span> <span class="hljs-title class_">MyMath</span> { @reverse <span class="hljs-title function_">calculate</span>(<span class="hljs-params">num1, num2</span>) { <span class="hljs-keyword">return</span> num1 + num2; } }

<span class="hljs-keyword">const</span> math = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyMath</span>(); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(math.<span class="hljs-title function_">calculate</span>(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>)); <span class="hljs-comment">// Output: 3</span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(math.<span class="hljs-property">calculate</span>.<span class="hljs-title function_">reversed</span>(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>)); <span class="hljs-comment">// Output: 3</span></pre></div><h1 id="2ddc">Automatic type checking</h1><p id="037c">Decorators can be applied to automatic type checking, for example, you can add a decorator to ensure that the type of a function parameter is correct.</p><div id="a63a"><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">checkType</span>(<span class="hljs-params">expectedType</span>) { <span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params">target, name, descriptor</span>) { <span class="hljs-keyword">const</span> originalMethod = descriptor.<span class="hljs-property">value</span>;

descriptor.<span class="hljs-property">value</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">...args</span>) {
      <span class="hljs-keyword">const</span> invalidArgs = args.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">arg</span> =&gt;</span> <span class="hljs-keyword">typeof</span> arg !== expectedType);
      <span class="hljs-keyword">if</span> (invalidArgs.<span class="hljs-property">length</span> &gt; <span class="hljs-number">0</span>) {
        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">`Invalid arguments: <span class="hljs-subst">${invalidArgs}</span>`</span>);
        <span class="hljs-keyword">return</span>;
      }
      <span class="hljs-keyword">return</span> originalMethod.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, args);
    };
    <span class="hljs-keyword">return</span> descriptor;
  }

}

<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyMath</span> { @<span class="hljs-title function_">checkType</span>(<span class="hljs-string">'number'</span>) <span class="hljs-title function_">add</span>(<span class="hljs-params">num1, num2</span>) { <span class="hljs-keyword">return</span> num1 + num2; } }

<span class="hljs-keyword">const</span> math = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyMath</span>(); math.<span class="hljs-title function_">add</span>(<span class="hljs-number">1</span>, <span class="hljs-string">'2'</span>); <span class="hljs-comment">// Output: Invalid arguments: 2</span></pre></div><p id="dd86"><i>More content at <a href="https://plainenglish.io/"><b>PlainEnglish.io</b></a>.</i></p><p id="5cf7"><i>Sign up for our <a href="http://newsletter.plainenglish.io/"><b>free weekly newsletter</b></a>. Follow us on <a href="https://twitter.com/inPlainEngHQ"><b>Twitter</b></a></i>, <a href="https://www.linkedin.com/company/inplainenglish/"><b><i>LinkedIn</i></b></a><i>, <a href="https://www.youtube.com/channel/UCtipWUghju290NWcn8jhyAw"><b>YouTube</b></a>, and <a href="https://discord.gg/GtDtUAvyhW"><b>Discord</b></a><b>.</b></i></p><p id="7057"><b><i>Interested in scaling your software startup</i></b><i>? Check out <a href="https://circuit.ooo?utm=publication-post-cta"><b>Circuit</b></a>.</i></p></article></body>

Day and Night

Poetry

Photo by Benjamin Balázs on Unsplash

The light and the dark both created by the almighty God While I love the glorification of one Can’t quite get why we villainise the other, everything doesn’t have to be a binary rung!

Both have, so much to give; without the night’s sleep, even the morning awakening becomes impossible to achieve So, I ask again why is night or darkness labelled as inauspicious? When the brightness and darkness, both seem to have their roles perfectly aligned, then why be judgemental of this nature, so divine!

Let’s not also forget sometimes even the light can be so overwhelming that the mind likes to drown into the void the darkness offers, besides When it is tough to open the eyes to confront the bright, it is the darkness which we seek, when we blink our eyes to make it easy right?

And, let’s not forget either, the times when we tend to open our eyes and mind, so comfortably, feel so safe and embraced, only, by taking refuge in the darkness’s shade Also, when it becomes too much to-do in the hustle-bustle of the morning’s bright, it is again the darkness in the night which becomes the solitude’s only respite!

Day or night; brightness or darkness, both deserve an applause, both win! One may show us the way ahead but the other shows us the way to the real light within!

Photo by Sven Scheuermeier on Unsplash

- GK

Self
Illumination
Poetry
Writing
Inspiration
Recommended from ReadMedium