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
Adavtages:
1 .First pattern can be used as a module which takes an object and return that object with some modification. In other words you can define such module as follows
var module = function (root) {
root.myFunction = function (foo) {
//do something
};
}
And use it like:
var obj = {};
module(obj);
So an advantage could be this module is reusable for later uses.
2 . In the first pattern as other answers already mentioned, you can define a private scope to store your private stuff such as private properties and methods. For example, consider this snippet codes
(function (root) {
// this plays as a private property
var factor = 3;
root.multiply = function (foo) {
return foo * factor;
};
})(MyObject);
3 . Another advantage could be this pattern can be used to add a method or property to all types of objects such as arrays, literal objects, functions
function sum(a, b){
return a + b;
}
(function (root) {
// this plays as a private property
var factor = 3;
root.multiply = function (foo) {
return foo * factor;
};
})(sum);
console.log(sum(1, 2)); // 3
console.log(sum.multiply(4)); // 12
Note: In my opinion the main advantage could be the second one (creating a private scope)
链接地址: http://www.djcxy.com/p/17062.html上一篇: JavaScript命名空间声明
下一篇: 这种定义JS对象的方式有什么用处吗?