title: JS| Initialised object is undefined after function accessing it is run more than once
body: <p>I am trying to reduce the global variables in my Chrome extension to reduce the 'spaghettiness' or ambiguity in my JavaScript.</p>
  <p>I am trying to attempt this by having an init function that declares these otherwise global variables within a mousedown eventListener callback function that is likely to be fired more than once.</p>
  <p>This is so that I can pass these variables + events through to other eventListener callbacks (namely a mouseup callback) as arguments of such callbacks.</p>
  <p>I have decomposed the issue into a separate file:</p>
  <p><strong>index.html</strong></p>
  <pre><code>&lt;!doctype html&gt;
  &lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;script src=&quot;test.js&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <p><strong>test.js</strong></p>
  <pre><code>isVarsInitOnce = false;
  
  function executesMoreThanOnce() {
      const initVariables = function() {
          console.log('runs once');
  
          const bools = {
              boolOne: false,
              boolTwo: false,
              boolThree: false
          };
  
          const events = {
              clickEvent:
                  function(event) {
                      //do stuff
                  },
              keyEvent:
                  function(event) {
                      //do other stuff
                  }
          };
  
          return {
              bools: bools,
              events: events
          }
      };
  
      if (!isVarsInitOnce) {
          isVarsInitOnce = true;
          let vars = initVariables();
  
          var booleanObject = vars.bools;
          var eventObject = vars.events;
      }
  
      console.log('objects: ', booleanObject, eventObject);
  
      //attempting to access initialised variable after function is executed more than once will cause an error.
      //this is because the booleanObject is now undefined.
      booleanObject.boolOne = true;
  }
  
  //runs twice
  for (let i=0; i&lt;2; i++) {
      executesMoreThanOnce();
  }
  </code></pre>
  <p>The method I have used to control the execution of the <code>initVariables()</code> is a global boolean variable, <code>isVarsInitOnce</code> which is effective at intialising the variables and setting the object for use in the <code>executesMoreThanOnce()</code> function once.</p>
  <p>The objects are able to be accessed in the first instance that the function is called in the <code>for</code> loop, however the objects are <code>undefined</code> when they are attempted to be accessed in the secondary instance that the function is called in the <code>for</code> loop.</p>
  <p>This is signified in rather clearly in the console output:</p>
  <pre><code>runs once
  test.js:38 objects:  {boolOne: false, boolTwo: false, boolThree: false} {clickEvent: ƒ, keyEvent: ƒ}
  test.js:38 objects:  undefined undefined //&lt;--- (function called 2nd time)
  test.js:42 Uncaught TypeError: Cannot set property 'boolOne' of undefined
      at executesMoreThanOnce (test.js:42)
      at test.js:47
  </code></pre>
  <p>I am unsure why this is occurring.</p>
  <p>Can anyone help me to understand why this does not work properly?</p>
  <p>Does anyone have a better suggestion for reducing global variables with regards to my case?</p>
  <p>Many thanks.</p>