Вопрос

Currently I'm developing a large scale Javascript app(single page) and I've searched around the web to find some best practices. Most projects use the module pattern so the objects doesn't pollute the global namespace. At this moment I use normal objects:

function LoginModel(){
    this.model = new MyModel();

    this.getModel = function(){
        return this.model;
    };
}

This is readable and easy to maintain(my opinion). Is it better to use the module pattern just because of the namespacing or does it has other advantages I'm not aware of(counter memory leaks, ... )? Furthermore, I've already splitted up the files to have a nice MVC pattern and destroy every object when needed(counter memory leaks). So the main question is: do I need, in my case, to use the module pattern or not?

Module pattern:

var LoginModel = (function(){
   var model = MyModel;

   function getModel(){
      return model;
   };

   return {
      getModel: getModel
   };
});
Это было полезно?

Решение 2

If you're only going to be using one instance per page, I don't see the need to involve the new keyword. So personally I would create a revealing module like you did in your last example, and expose an object with the "public" properties.

Though I don't see your point with the getModel() function, since MyModel is obviously accessable outside of the scope.

I would have rewritten it slightly:

var LoginModel = (function(model, window, undefined){

    function init(){ } // or whatever

    function doSomethingWithModel(){
        console.log(model);
    }

    return { init: init };

})(MyModel, window);

If you're uncertain of which modules that will get a model, you can use loose augumentation and change

})(MyModel, window);

to

})(MyModel || {}, window);

If you need several instances of a module, it would look something like this:

var LoginModel = (function(model, window, undefined){

    function loginModel(name){ // constructor
        this.name = name; // something instance specific
    }

    loginModel.prototype.getName = function(){
        return this.name;
    };

    return loginModel;

})(MyModel, window);

var lm1 = new LoginModel('foo');
var lm2 = new LoginModel('bar');

console.log(lm1.getName(), lm2.getName()); // 'foo', 'bar'

Другие советы

The module pattern is better for overall code organization. It lets you have data, logic and functions that are private to that scope.

In your second example getModel() is the only way to get the model from the outside. The variable declared int he module are hidden unless explicitly exposed. This can be a very handy thing.

And there's not really any drawback, other than being a little more complex. You just get more options for organization and encapsulation.

I'd use a plain object until my model gets complex enough to need more structure and some private scoping. And when you hit that point, it's trivial to redefine it as a revealing module without breaking any of the code that uses it.

There's several concepts conflated in your question

With what you call the "normal object", the function becomes a constructor function and requires the new keyword.

The second example uses the Revealing Module Pattern inside of an IIFE. This is the most popular variant of the Module Pattern, but unfortunately deeply flawed. For an explanation of the differences see my answer here, and for its flaws, see here.

Now, your question poses a false dichotomy -- normal objects or module pattern? You don't have to make a choice -- a normal object can use the module pattern simply by putting whatever it wants to keep private inside its closure scope. For example,

function LoginModel(){
    var _notifyListeners = function(){ 
        // Do your stuff here
    };

    this.model = new MyModel();

    this.getModel = function(){
        _notifyListeners();
        return this.model;
    };
}

This is an example of a "normal object" using the module pattern. What you have to avoid doing is what the Revealing Module Pattern does -- putting everything into closure scope. You should only put the things you want to keep private inside the closure scope.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top