javascript全局使用模块的一个实例的最佳实践

时间:2015-10-01 03:40:58

标签: javascript module requirejs browserify

我有javascript模块节点用户

节点是一个类:

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

用户 一个类:

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

然后我在 main 中运行所有内容,它通过RequireJS抓取依赖项,初始化用户,然后创建一些节点,然后调用依赖于用户的Node属性:

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

有一些非常具体的问题。

  1. 即使只有一个用户实例,是否有充分的理由让它成为一个类? (这是一个不太重要的问题,主要是它的重要性取决于它与以下问题的联系......)

  2. 节点和主要导入用户。这是否意味着将有两份用户副本?如果我在main中初始化用户,然后尝试从Node访问它,我将访问该SAME INITIALIZED用户吗?

  3. 获得此行为的“最佳做法”是什么,只有一个用户对象在多个模块(主要,节点和其他可能的其他模块)之间共享?我在考虑使用window.user = user而不是return user,但我想确保以正确的方式做事。 (同样重要的是要考虑我目前正在使用RequireJS,但很快就会切换到Browserify。特定于任何一个工具的解决方案可能是件坏事。我愿意使用Babel支持的ES6功能,因此将在今天和未来发挥作用。)

1 个答案:

答案 0 :(得分:1)

问题2的答案是只存在int的一个实例。 AMD加载器(和CommonJS环境一样)加载并执行一次每个模块,然后缓存其返回值。

因此,问题3的答案是你不需要做任何特别的事情。暴露全局会适得其反(模块之一是你不应该污染全局命名空间)。

对于问题1,如果不需要成为一个类,没有理由做出一个类,特别是如果它应该代表一个单独的实例。为什么在只能返回单个对象时创建具有单例模式的类?你已经可以实现"私人"仅通过在模块的工厂功能的闭包内定义函数来起作用,这些函数不会在返回值上公开。