Home > Enterprise >  How to use this in javascript module pattern?
How to use this in javascript module pattern?

Time:09-06

I'm studying module pattern and have a question.

I want to use 'settings' anywhere.


script1.js

var MODULE = (function() {
  var t = {};
  this.settings = { // this == Window
    users: ['john', 'emma']
  }
  return t;
})()

script2.js

MODULE.dom = function() {
  var t = this; // this == MODULE

  document.querySelector('p').textContent = t.settings.users[0]; // error

  function _say() {
    return t.settings.users[1] // error
  }

  return {
    say: _say
  }
}

MODULE.DOM = MODULE.dom.call(MODULE)

When use this.settings = {...}, 'this' means Window so code doesn't work.

When use t.settings = {...}, 'this' means MODULE so code works but when write MODULE in dev console, settings is exposed in MODULE variable. Is it ok?

I'd greatly appreciate any help, thank you!

CodePudding user response:

When use t.settings = {...}, 'this' means MODULE so code works

That's the right way to do it.

but when write MODULE in dev console, settings is exposed in MODULE variable. Is it ok?

It's mostly OK.

If you're worried about the client being able to type in the variable name and see the code that gets run - there's no way to avoid that. They can just look at the devtools to see what the network requests are, and what is downloaded - or look at the Sources panel.

If you're worried about running into naming collisions with larger scripts, then - sometimes, libraries deliberately assign themselves to the window to allow other parts of the code to access them. Perhaps you'd like your MODULE to be like this. If not, then you should utilize JavaScript modules instead, which allow for scripts to be imported inside other scripts without polluting the global namespace at all or having any possibility of naming collisions. For example, you could do

// script1.js
export const MODULE = {
  settings: {
    users: ['john', 'emma'];
  }
};
// script2.js
import { MODULE } from './script1.js';
// proceed to use MODULE

And you can do import { MODULE } from './script1.js'; from any script file, not just script2.js.

Personally, I consider the IIFE module pattern in JavaScript to be mostly obsolete nowadays. For any reasonable-sized script, better to write code in separate files and then import and export as needed. (A 1000 line file is somewhat hard to debug and refactor. Ten 100 line files are easier to debug and refactor.)

  • Related