What is the advantage of using this JavaScript coding pattern to define constructor functions?
Asked Answered
P

4

9

I tend to write object constructors in the following way:

function Person(name) {
    this.name = name;
}
Person.prototype.greet = function () {
    alert("Hello! My name is " + this.name + ".");
};

I've noticed a few JavaScript libraries and frameworks adding some extra code around that like so:

var Person = (function () {
    function Person(name) {
        this.name = name;
    }
    Person.prototype.greet = function () {
        alert("Hello! My name is " + this.name + ".");
    };
    return Person;
})();

I know what the self-executing anonymous function does and is used for. What I fail to see at the moment is what advantage or benefit this provides when defining a constructor and its prototype.

EDIT #1:

I know the module pattern and its advantages, and use it fairly often in my coding. My mistake in communication was not being clear that my first code sample is not supposed to be in the global scope. I always wrap all of my external JavaScript files in a self-executing anonymous function to enforce local scope on the code.

For instance:

;(function ( window, undefined ) {
    var p = function (name) {
        this.name;
    };
    p.prototype.greet = function () {
        alert("Hello! My name is " + this.name + ".");
    };
    window.Person = window.Person || p;
})(window);

The thing is that I've seen the technique displayed in my second code sample used within such an anonymous function.

For instance:

;(function ( window, undefined ) {
    var p = (function () {
        var q = function (name) {
            this.name = name;
        };
        q.prototype.greet = function () {
            alert("Hello! My name is " + this.name + ".");
        };
        return q;
    })();
    window.Person = window.Person || p;
})(window);

This is where I'm at a loss for the significance of the technique.

Painting answered 15/2, 2012 at 22:0 Comment(2)
In this specific example, there is no difference. I think for a more complicated class, it might matter, depending on what the framework is doing inside the extra scope.Nephograph
@Nephograph - Yours is along the lines of the answer I was hoping for. I wonder if anyone might be able to elaborate more on this.Painting
H
1

The second method, the module pattern, is more portable. Notice that you can name Person to anything you want.

At the first method, you would have to keep track of every occurrence of Person, and be careful to not accidentally delete part of the method when copying the constructor+prototype to another project.

The second method has an additional advantage: You can use local/temporary/throw-away variables which can be used to dynamically define constants/methods/properties on the namespace.

Huynh answered 15/2, 2012 at 22:2 Comment(0)
W
1

It's effectively a namespace isn't it?

Waterloo answered 15/2, 2012 at 22:3 Comment(2)
No, you're right. And this is often what this pattern is used for; to avoid polluting the global namespace by wrapping everything in a closure.Ornithosis
Na, I'd say there's difference between "namespace" and "closure". Of course the window object is something like a namespace, and you can use closures to populate namespaces, but not in these examples.Nicknack
H
0

I preferer first solution, less code more clear for me.

I see the second solution better only if you copy paste often your code to other library, but I don't think this is a good reason

Hamamelidaceous answered 15/2, 2012 at 22:4 Comment(0)
P
0

This is the answer that my co-worker, who has an uncanny knowledge of not just JavaScript but how all the various JavaScript engines in browsers works, told me that this pattern of code is an unnecessary and overly defensive way to define objects that is used to deal with faults in certain JavaScript parsers (he specifically cited versions of Opera) that allow for scope creep. It certainly sounds like a reasonable answer...

Painting answered 13/4, 2012 at 16:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.