1

So i have this function. I am trying to get a new Test('selector', {}) from outside this js file, it comes undefined and i can't seem to figure out why.

Do i really need to attach it to the window object ? Can someone explain this ?

TO mention it works from the same file.

let Test = ((window, document, undefined) => {

  class test {
    constructor(selector, options) {
     this.selector = document.querySelector(selector);
     this.options = options;
    }
 }

 return test;

})(window, document);

This is my webpack config file:

module.exports = {
 entry: './src/test.js',
 module: {
   loaders: [
     {
       test: /\.js?$/,
       exclude: / (node_modules) /,
       loader: 'babel-loader',
       query: {
         presets: ['es2015', 'stage-0']
       }
     }
   ]
 },
 output:  {
   path: __dirname + '/src',
   filename: 'test.min.js'
 }
}
  • 1
    IIFEs are still functions, and functions have their own scope unrelated to global scope. Variables declared in function scope vanish when the function has finished executing. If you want it to persist after the IIFE, yes, you need to either declare it outside the function or attach the _value_ of the class outside. – Akshat Mahajan May 22 '16 at 20:25
  • There is no benefit to pass *window* to the function, use global *this* instead: `((window, document, undefined) => {...})(this, document)` since they are the same object in a browser and *this* must reference the global object, *window* may not as it can be reassigned. And within the arrow function, *this* must reference the global object anyway. – RobG May 22 '16 at 21:12
  • @AkshatMahajan: [Nope](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work). – Bergi May 22 '16 at 21:17
  • What do you mean by "*it works from the same file*"? How are you executing this script? Are you transpiling it? Are you accidentally treating it as a module? – Bergi May 22 '16 at 21:19
  • @Bergi it seems to work without transpiling it. Can you please explain what do you mean by Are you accidentally treating it as a module? –  May 24 '16 at 16:32
  • If it is executed as a module, not as a script, then `let Test` will create a module-scope variable not a global one. – Bergi May 24 '16 at 17:37
  • @Bergi thank you for your answer, any suggestions on how to avoid that ? –  May 24 '16 at 20:25
  • It should be an option of your transpiler, check its docs (and show us what you are using). – Bergi May 24 '16 at 20:27

1 Answers1

4

I was clearly misunderstanding what webpack is doing. Webpack turns all your JavaScript files into modules that are not available in the global namespace. That's why we need to use require/import to load them in. In the above example the Test function was never loaded in and is not defined. The default scoping nature of JavaScript no longer exists.