<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
    <title>JavaScript Rules - memoization</title>
    <link href="http://javascriptrules.com/tag/memoization.xml" rel="self"/>
    <link href="http://javascriptrules.com"/>
    <updated>2012-03-08T18:28:28-08:00</updated>
    <id>http://javascriptrules.com/tag/memoization</id>
    <author>
        <name>Marcel Duran</name>
        <email>marcelduran@gmail.com</email>
    </author>
 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    <entry>
        <title>Cross-browser event listener with design patterns</title>
        <link href="http://javascriptrules.com/2009/07/22/cross-browser-event-listener-with-design-patterns"/>
        <updated>2009-07-22T00:00:00-07:00</updated>
        <id>/2009/07/22/cross-browser-event-listener-with-design-patterns</id>
        <content type="html">&lt;p&gt;A lot of the power of JavaScript comes from the ability to be an event-driven language. Dealing with event listeners is not a simple task considering different implementations by Internet Explorer and the rest of the world. After some searching on internet you have probably found some cross-browser solutions, although they are not always as efficient as it possibly could.&lt;br /&gt;I&amp;#8217;ll present some of them and explain their design pros and cons. All them do exactly the same, attach actions to events, none of them does &lt;a href='http://en.wikipedia.org/wiki/Browser_sniffing'&gt;browser sniffing&lt;/a&gt; to determine which event attachment technique to use, they use feature detection instead. For clarity sake, browser sniffing is a common technique on which an application tries to find out the user&amp;#8217;s browser, usually by examining the useragent string looking for vendor/version and is a common source of detection problems. On the other hand, feature detection is a much safer technique where the application checks if a certain feature (function, property) exists (is implemented) in the browser and once this feature is defined, use it, otherwise another feature is checked as a fallback.&lt;br /&gt;Some &lt;a href='http://en.wikipedia.org/wiki/Design_pattern_(computer_science)'&gt;design patterns&lt;/a&gt; presented here are well covered in &lt;a href='http://www.javascriptrules.com/books/#rossharmes-dustindiaz'&gt;Ross Harmes &amp;amp; Dustin Diaz&amp;#8217;s Pro JavaScript Design Patterns&lt;/a&gt; book.&lt;/p&gt;

&lt;h3 id='facade'&gt;facade&lt;/h3&gt;

&lt;p&gt;Very intuitive and also popular when quick searching on internet. Here the facade pattern simplifies the interface for attaching events by providing a common method to be used on your code which does the task of detecting features in order to provide a safe cross-browser implementation.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='lineno'&gt;1&lt;/span&gt; &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;2&lt;/span&gt;     &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;3&lt;/span&gt;         &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;4&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;5&lt;/span&gt;         &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;6&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;7&lt;/span&gt;         &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt;8&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='lineno'&gt;9&lt;/span&gt; &lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;pros:&lt;/strong&gt; easy and clear to understand, small.&lt;br /&gt;&lt;strong&gt;cons:&lt;/strong&gt; inefficient when used consecutive times, every time it&amp;#8217;s called a new checking is made in order to determine which feature is available for attaching event listeners.&lt;/p&gt;

&lt;h3 id='memoization_version_a'&gt;memoization &lt;em&gt;version a&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;Function rewriting is a powerful feature on JavaScript, it allows a function to be redefined by itself. When a function is invoked it can perform some tasks and before it returns, it can be redefined. Here memoization happens on lines 4, 9 and 14 depending on which feature is available in the host environment (browser). During the feature detection on this &lt;em&gt;version a&lt;/em&gt; of memoization, the appropriate event attacher is first invoked then the function is rewritten.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='lineno'&gt; 1&lt;/span&gt; &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 2&lt;/span&gt;     &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 3&lt;/span&gt;         &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 4&lt;/span&gt;         &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 5&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 6&lt;/span&gt;         &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt; 7&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 8&lt;/span&gt;         &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 9&lt;/span&gt;         &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;10&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;11&lt;/span&gt;         &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;12&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;13&lt;/span&gt;         &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt;14&lt;/span&gt;         &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;15&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;  &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt;16&lt;/span&gt;         &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;17&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='lineno'&gt;18&lt;/span&gt; &lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;pros:&lt;/strong&gt; very efficient, feature detection is made only once as the addEvent function is rewritten with the appropriate event listener attacher function.&lt;br /&gt;&lt;strong&gt;cons:&lt;/strong&gt; cost of the event listener function invocation prior to function rewriting, cost of function rewriting.&lt;/p&gt;

&lt;h3 id='memoization_version_b'&gt;memoization &lt;em&gt;version b&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;This technique is pretty similar to the one above except that during the feature detection the function is first rewritten with the appropriate event attacher then it is invoked only in the first execution.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='lineno'&gt; 1&lt;/span&gt; &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 2&lt;/span&gt;     &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 3&lt;/span&gt;         &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 4&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 5&lt;/span&gt;         &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt; 6&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 7&lt;/span&gt;         &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 8&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 9&lt;/span&gt;         &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;10&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;11&lt;/span&gt;         &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;12&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;  &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt;13&lt;/span&gt;         &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;14&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='lineno'&gt;15&lt;/span&gt;     &lt;span class='nx'&gt;addEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;16&lt;/span&gt; &lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;pros:&lt;/strong&gt; as efficient as version a, feature detection is made only once too.&lt;br /&gt;&lt;strong&gt;cons:&lt;/strong&gt; cost of function rewriting first then cost of first invocation.&lt;/p&gt;

&lt;h3 id='closure'&gt;closure&lt;/h3&gt;

&lt;p&gt;A closure is a protected variable space, created by using nested functions.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='lineno'&gt; 1&lt;/span&gt; &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 2&lt;/span&gt;     &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 3&lt;/span&gt;         &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 4&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 5&lt;/span&gt;         &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt; 6&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 7&lt;/span&gt;         &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 8&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 9&lt;/span&gt;         &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;10&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;11&lt;/span&gt;         &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;12&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;  &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt;13&lt;/span&gt;         &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;14&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='lineno'&gt;15&lt;/span&gt; &lt;span class='p'&gt;}());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;pros:&lt;/strong&gt; detection is made as soon as the script where this function resides in is executed (note parenthesis on line 15), hence the detection is made only once, returning the appropriate event listener attacher to be used on new calls, useful when using it consecutively.&lt;br /&gt;&lt;strong&gt;cons:&lt;/strong&gt; initial execution cost as it is executed right after loading, but considering its size and complexity can barely be noticed. Can be a bit obscure for beginners unfamiliar with closures. For those I suggest reading &lt;a href='http://www.crockford.com/javascript/private.html'&gt;Douglas Crockford&amp;#8217;s Private Members in JavaScript&lt;/a&gt;. Closure consumes more memory because it carries with them the containing function&amp;#8217;s scope.&lt;/p&gt;

&lt;h3 id='closure__singleton__lazy_loading_this_technique_makes_use_of_3_patterns'&gt;closure + singleton + lazy loading This technique makes use of 3 patterns:&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;closure&lt;/strong&gt; is defined by nested functions (lines 1 and 4) where the inner function (line 4) has access to its outer function variable &lt;em&gt;setListener&lt;/em&gt; (line 2), it is invoked on line 22.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;singleton&lt;/strong&gt; is defined by using a single variable (line 2) that defines a function on lines 7, 11 and 15. It is checked on line 5 and always invoked on line 20.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;lazy loading&lt;/strong&gt; is used here for assigning the singleton variable when demanded as opposed to immediately after singleton definition.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='lineno'&gt; 1&lt;/span&gt; &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 2&lt;/span&gt;     &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;setListener&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt; 3&lt;/span&gt; 
&lt;span class='lineno'&gt; 4&lt;/span&gt;     &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 5&lt;/span&gt;         &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='nx'&gt;setListener&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 6&lt;/span&gt;             &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 7&lt;/span&gt;                 &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 8&lt;/span&gt;                     &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 9&lt;/span&gt;                 &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;10&lt;/span&gt;             &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;11&lt;/span&gt;                 &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;12&lt;/span&gt;                     &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;13&lt;/span&gt;                 &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;14&lt;/span&gt;             &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;15&lt;/span&gt;                 &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;16&lt;/span&gt;                     &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;  &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt;17&lt;/span&gt;                 &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;18&lt;/span&gt;             &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='lineno'&gt;19&lt;/span&gt;         &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='lineno'&gt;20&lt;/span&gt;         &lt;span class='nx'&gt;setListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;21&lt;/span&gt;     &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;22&lt;/span&gt; &lt;span class='p'&gt;}());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;pros:&lt;/strong&gt; no time consuming when script is loaded, first execution (closure) is very fast as it only returns a function, event listener attacher is defined only once on demand.&lt;br /&gt;&lt;strong&gt;cons:&lt;/strong&gt; it can be a bit obscure by mixing up 3 different techniques, after the first invocation every subsequent invocation has a verification on line 5 which will always return false however this is very subtle and also very cheap in JavaScript. All cons listed on closure pattern above.&lt;/p&gt;

&lt;h3 id='closure__memoization_version_a'&gt;closure + memoization &lt;strong&gt;version a&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Here, closure takes part by returning an inner function that has access to its outer function &lt;em&gt;setListener&lt;/em&gt; on line 2, it immediately invoked on line 24 returning a function that invokes &lt;em&gt;setListener&lt;/em&gt; function. Within &lt;em&gt;setListener&lt;/em&gt; function definition (lines 2-19) the memoization takes part inside every &lt;em&gt;if-else&lt;/em&gt; by rewriting itself with the appropriate event attacher. In this technique the appropriate event attacher is first invoked during feature detection then the &lt;em&gt;setListener&lt;/em&gt; function is rewritten.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='lineno'&gt; 1&lt;/span&gt; &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 2&lt;/span&gt;     &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 3&lt;/span&gt;         &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 4&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 5&lt;/span&gt;             &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 6&lt;/span&gt;                 &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 7&lt;/span&gt;             &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt; 8&lt;/span&gt;         &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 9&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;10&lt;/span&gt;             &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;11&lt;/span&gt;                 &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;12&lt;/span&gt;             &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;13&lt;/span&gt;         &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;14&lt;/span&gt;             &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;  &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt;15&lt;/span&gt;             &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;16&lt;/span&gt;                 &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;  &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt;17&lt;/span&gt;             &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;18&lt;/span&gt;         &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='lineno'&gt;19&lt;/span&gt;     &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;20&lt;/span&gt; 
&lt;span class='lineno'&gt;21&lt;/span&gt;     &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;22&lt;/span&gt;         &lt;span class='nx'&gt;setListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;23&lt;/span&gt;     &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;24&lt;/span&gt; &lt;span class='p'&gt;}());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;pros:&lt;/strong&gt; very efficient when used consecutively, pretty elegant code (you can use to impress your boss)&lt;br /&gt;&lt;strong&gt;cons:&lt;/strong&gt; it can also be a bit obscure, specially for those not familiar to JavaScript patterns. All cons listed on closure pattern above.&lt;/p&gt;

&lt;h3 id='closure__memoization_version_b'&gt;closure + memoization &lt;em&gt;version b&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;This technique is pretty much the same as above the only difference is that during feature detection which happens only once, the &lt;em&gt;setListener&lt;/em&gt; function is first rewritten (lines 4,8,12) then it&amp;#8217;s invoked on line 16, only during the first call.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='lineno'&gt; 1&lt;/span&gt; &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;addEvent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 2&lt;/span&gt;     &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 3&lt;/span&gt;         &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 4&lt;/span&gt;             &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 5&lt;/span&gt;                 &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addEventListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt; 6&lt;/span&gt;             &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt; 7&lt;/span&gt;         &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 8&lt;/span&gt;             &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt; 9&lt;/span&gt;                 &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attachEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;10&lt;/span&gt;             &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;11&lt;/span&gt;         &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;12&lt;/span&gt;             &lt;span class='nx'&gt;setListener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;13&lt;/span&gt;                 &lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;  &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='lineno'&gt;14&lt;/span&gt;             &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;15&lt;/span&gt;         &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='lineno'&gt;16&lt;/span&gt;         &lt;span class='nx'&gt;setListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;17&lt;/span&gt;     &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;18&lt;/span&gt; 
&lt;span class='lineno'&gt;19&lt;/span&gt;     &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='lineno'&gt;20&lt;/span&gt;         &lt;span class='nx'&gt;setListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='lineno'&gt;21&lt;/span&gt;     &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='lineno'&gt;22&lt;/span&gt; &lt;span class='p'&gt;}());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;pros:&lt;/strong&gt; same &lt;em&gt;pros&lt;/em&gt; on &lt;em&gt;version a&lt;/em&gt; above&lt;br /&gt;&lt;strong&gt;cons:&lt;/strong&gt; same &lt;em&gt;cons&lt;/em&gt; on &lt;em&gt;version a&lt;/em&gt; above&lt;/p&gt;

&lt;h3 id='conclusion'&gt;conclusion&lt;/h3&gt;

&lt;p&gt;Very different techniques were presented in this post, all them have their pros and cons, it&amp;#8217;s up to the developer to choose which one to use, however the facade one is not indicated for performance issues but it can be useful to explain/introduce this design patterns for beginners.&lt;br /&gt;The examples above uses the most common JavaScript design patterns and can be combined in your applications for different purposes rather then event attacher, chosen for being a real world situation where developers face everyday.&lt;/p&gt;</content>
    </entry>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
 
</feed>

