简体   繁体   中英

javascript best practice to use one instance of a module globally

I have the javascript modules Node and user .

Node is a class:

define(["underscore", "user"], function(_, User) {

class Node {
   // one of the Node attributes needs to access user.prefs in order to figure out what style to output its output in.  user should already be initialized at that point, and it is this initialized version of user that Node must access.
}

return Node

}) // end of define

user is not a class:

define(['underscore'], function(_) {

user = {}
function init({username, password}) {
        user.username = username
        // open oauth stuff with username and password
        user.prefs = _.defaults(this._initPrefs(), {
            display_name_capitalization: "title", // bla
            underline_definitions: false, // blablabla
            show_description_on_hover: false, // blabla
        })
}

return user

}) // end of define

Then I run everything in main , which grabs the dependencies via RequireJS, initializes user, then creates some Nodes, and then calls that Node attribute which depends on user:

require(["node", "user"], function(Node, user) {

user.init({
  username: 'Tim',
  password: 'TinyButMighty!',
})
for (n of retrieved_nodes) {
  n = new Node(n)
  doSomethingWith(n.attribute_that_depends_on_user)
}

}) // end of require

There are some very specific questions that come out of this.

  1. Even though there will only be ONE instance of user, is there a good reason to make it a class? (this is a less important question, and mostly it's importance depends upon its connection to the following question...)

  2. Both Node and main import user. Does that mean there will be TWO copies of user? If I initialize user in main, and then try to access it from Node, will I access that SAME INITIALIZED user?

  3. What is the "best practice" for getting this behavior where there is only one user object that is shared across multiple modules (main, Node, and possibly others)? I was thinking of using window.user = user instead of using return user , but I want to make sure I do things the right way. (It is also important to consider that I am currently using RequireJS, but will soon switch to Browserify. A solution to specific to any one tool could be a bad thing. I am open to using ES6 features that are supported by Babel, and therefore will work today and in the future.)

The answer to question 2 is that only one instance of user will exist. AMD loaders (and CommonJS environments alike) load and execute each module once, then cache its return value.

It follows that the answer to question 3 is that you don't need to do anything special. Exposing a global would be counter-productive (one of the takeaways of modules is that you shouldn't need to pollute the global namespace).

As for question 1, there's no reason to make something a class if it doesn't need to be one, and especially if it's supposed to represent a single instance anyway. Why create a class with a singleton pattern when you can just return a single object anyway? You can already achieve "private" functions simply by defining functions within the closure of the module's factory function, that aren't exposed on the return value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM