Does this way of defining JS objects have any purpose?

I'm maintaining some legacy code and I've noticed that the following pattern for defining objects is used:

var MyObject = {};

(function (root) {

    root.myFunction = function (foo) {
        //do something
    };

})(MyObject);

Is there any purpose to this? Is it equivalent to just doing the following?

var MyObject = {

    myFunction : function (foo) {
        //do something
    };

};

I'm not about to embark in a holy quest to refactor the whole codebase to my likings, but I'd really like to understand the reason behind that roundabout way of defining objects.

Thanks!


It's called the module pattern http://toddmotto.com/mastering-the-module-pattern/

The main reason is for you to create truly private methods and variables. In your case, it's not meaningful because it's not hiding any implementation details.

Here's an example where it makes sense to use the module pattern.

var MyNameSpace = {};

(function(ns){
    // The value variable is hidden from the outside world
    var value = 0;

    // So is this function
    function adder(num) {
       return num + 1;
    }

    ns.getNext = function () {
       return value = adder(value);
    }
})(MyNameSpace);

var id = MyNameSpace.getNext(); // 1
var otherId = MyNameSpace.getNext(); // 2
var otherId = MyNameSpace.getNext(); // 3

Whereas if you just used a straight object, adder and value would become public

var MyNameSpace = {
    value: 0,
    adder: function(num) {
       return num + 1;
    },
    getNext: function() {
       return this.value = this.adder(this.value);
    }
}

And you could break it by doing stuff like

MyNameSpace.getNext(); // 1
MyNameSpace.value = 0;
MyNameSpace.getNext(); // 1 again
delete MyNameSpace.adder;
MyNameSpace.getNext(); // error undefined is not a function

But with the module version

MyNameSpace.getNext(); // 1
 // Is not affecting the internal value, it's creating a new property
MyNameSpace.value = 0;
MyNameSpace.getNext(); // 2, yessss
// Is not deleting anything
delete MyNameSpace.adder;
MyNameSpace.getNext(); // no problemo, outputs 3

The purpose is to limit accessibility of functions within the closure to help prevent other scripts from executing code on it. By wrapping it around a closure you are redefining the scope of execution for all code inside the closure and effectively creating a private scope. See this article for more info:

http://lupomontero.com/using-javascript-closures-to-create-private-scopes/

From the article:

One of the best known problems in JavaScript is its dependance on a global scope, which basically means that any variables you declare outside of a function live in the same name space: the ominous window object. Because of the nature of web pages, many scripts from different sources can (and will) run on the same page sharing a common global scope and this can be a really really bad thing as it can lead to name collisions (variables with the same names being overwritten) and security issues. To minimise the problem we can use JavaScript's powerful closures to create private scopes where we can be sure our variables are invisible to other scripts on the page.



Code:

var MyObject = {};

(function (root) {
    function myPrivateFunction() {
       return "I can only be called from within the closure";
    }

    root.myFunction = function (foo) {
        //do something
    };    

    myPrivateFunction(); // returns "I can only be called from within the closure"

})(MyObject);


myPrivateFunction(); // throws error - undefined is not a function

advantages:

  • maintains variables in private scope.

  • you can extend the functionality of the existing object.

  • performance is increased.

  • i think the above three simple points are just enough to follow those rules. And to keep it simple its nothing but writing inner functions.

    链接地址: http://www.djcxy.com/p/94842.html

    上一篇: 实体类型ApplicationUser不是当前上下文的模型的一部分

    下一篇: 这种定义JS对象的方式有什么用处吗?