开发者

What kind of a pattern/object is this in Javascript?

I see this pattern a lot (which I actually use) but I want an explanation as to how it works.

var mystuff = function() {


    var blah = function() {开发者_JS百科

    };


    return {

        setup: function() {
              blah();
        };

    };


}();

Then usage is very OOP like:

mystuff.setup();


What that's doing is returning a public interface to your object. It looks like you are using the public setup() function to access the private blah() function. This is one method of emulating public and private member functions in Javascript objects.

Since mystuff is defined with that trailing () at the bottom, it's executed immediately when the parser reaches mystuff.setup(), and actually returns an anonymous object (your public interface) with the setup() method.


Others have explained how it works. This is just somemore background info on the topic.

It's called the "Module pattern" (coined by Douglas Crockford I believe, but blogged about earlier).

It gives you three main benefits:

  1. A namespace (the value to the left of "function")
  2. A private "space" to put stuff in (vars, functions, etc) that don't need or should not pollute the global namespace (this is the stuff before the return statement)
  3. A public "space" to put stuff that you want accessible to users of your namespace (this is the return statement)

all in a fairly readable form.


This is simply an example of nested functions in JavaScript. Although the method of calling them may seem "OOP-like" on the surface, this style very much belongs to the functional paradigm.

In essence, however, there's nothing too fancy going on. JavaScript is known as a language in which "everything is a function", which is close enough to the truth. All it means is that any function declared belongs strictly to its parent scope.


It's from a functional programming approach to object oriented programming. Local variables in the outer (anonymous) function (the constructor) are accessible to any function defined within the constructor, but not elsewhere, making the local variables private. Where it differs from the purely functional approach is that the constructor returns an object literal rather than another function. The local variables are accessible by inner functions due to what's termed a closure.

It's use is to create private fields & methods, in the form of local variables.


but I want an explanation as to how it works.

Let's desect it piece by piece.

function() { .... } is a syntax for anonymous function.
function() { .... }() is defining and calling the anonymous function on the same line.

The return value of the function in your sample is an object defined using JSON notation (Javscript Object Notation)

{ setup : .... } is an object with one attribute: it's called setup, and it happens to be a function, in your case.

so, mystuff got the return value, which is an object with a property (function) called setup, and mystuff.setup() invokes this setup function.

Now, the interesting part is probably how setup just calls the blah function, defined inside that enclosing anonymous function.

I believe the technical term here is closure (see the section forming closures) (Also see the wikipedia definition)

Essentially the function becomes like a module of its own, with variables bound to it.

It's explained in crescentfresh's answer


First of all, please avoid this syntax:

var mystuff=function(){...}();

It is bad coding practice since it isn't completely cross-browser as a few browsers will error here. Get used to putting parentheses around the function like so:\

var mystuff=(function(){...})();

Nextly, regarding the pattern. This pattern is more commonly known as simply "encapsulation" in JavaScript. Closures is another possibly but more specifically it is purely encapsulation in this case.

Encapsulation simply means you are making some members private. What is private in this case? Well the blah variable is private in this case. Please get into the habit of proceeding private members with an underscore to indiciate they are private. It is good coding practice to distinguish public methods from private methods with an underscore.

<script type="text/javascript">
var obj=(function(){
    //private members
    var _p={};//toss all private members into a single object.
    _p.list=[];
    _p.init=function(){
        _p.list=[];
    };

    //public members. use "this" to reference object followed by the method.
    //however obj._p.list won't be accessible to the global scope
    return {
        reset:function()
         {
            _p.init();
         }
        ,addName:function(str)
         {
            _p.list.push(''+str);//limit to strings
         }
         ,getNames:function()
          {
            return _p.list.slice(0);//return a clone
          }
         ,alertNames:function()
          {
            alert(this.getNames().join(","));
          }
         ,getPrivateObj:function()
          {
            return _p;
          }
    };
})();

obj.alertNames();
obj.addName("Nandan");
obj.addName("Ram");
obj.alertNames();
obj.reset();
obj.alertNames();
obj.addName("Vinoth");
obj.addName("Kevin");
obj.alertNames();
alert(typeof obj._p);//undefined
var privateObj=obj.getPrivateObj();
alert(typeof privateObj);
alert(privateObj.list.join("|"));
</script>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜