Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have not yet found a common way on the Internet for creating a namespace in JavaScript.
What's the best way to create a namespace (and please list any downfalls that particular approach might have).
(function() {
var usefulVariable;
var foo = {
bar:function(){ alert('hi') }
};
// leak into global namespace
window.foo = foo;
})();
Only foo is exposed to the global namespace, and it "lives" within your private self executing anon function namespace.
In JavaScript, namespaces can only be achieved through object literals, which can be as simple as this:
var MyNS = {
f1: function() {...},
f2: function() {...}
};
As others have attempted to show, if you want to provide a private scope within your namespace (which is suggested), the following method is the most appropriate:
var MyNS = (function() {
var private1 = "...",
private2 = "...";
return {
f1: function() {...},
f2: function() {...}
}
})();
The book Pro JavaScript Design Patterns (Harmes & Diaz, 2008) provides examples of namespace creation using simple object literals or self-executing anonymous functions, both of which are illustrated in Justin Johnson's excellent answer, and these approaches work well.
Depending on the situation, it might be possible that the namespace already exists and contains members. In such a case, these approaches would destroy any members in the namespace. If this is a concern, one can use an approach similar to this to preserve any existing members, while adding new ones:
var myNamespace = (function(ns) {
ns.f1 = function() { ... };
ns.f2 = function() { ... };
return ns;
})(window.myNamespace || {});
Here, myNamespace is assigned the value returned by the anonymous, self-executing function that receives the parameter ns. As one can see, the value of this parameter is either window.myNamespace or an empty object, depending on whether or not myNamespace has been previously declared.
Here's my favorite way. It's a little unorthodox but it works well.
var MyNamespace = new function(){
this.MY_CONST_ONE = 1;
this.MY_CONST_TWO = 2;
this.MyClass = function (x) {
this.x = x;
}
this.MyOtherClass = function (y) {
this.y = y;
}
} // end of namespace
// ...
var oc = new MyNamespace.MyOtherClass(123);
The interesting thing about it is the closure function is called with new instead of the normal parenthesis, so directly inside of it this refers to the object returned by the function, in other words, the 'namespace' itself.
I generally try to keep it simple and create a global object representing the namespace. If you are using multiple scripts, each declaring the namespace because they might each be used in different applications, then you would probably want to check if the object already exists.
//create the namespace - this will actually obliterate any pre-existing
//object with the same name in the global namespace
//(and this does happen).
//NB ommiting the var keyword automatically chucks the object
//variable into the global namespace - which ordinarily you
//don't want to do
MyNameSpace = {};
//and then create a class/object in the namespace
MyNameSpace.MyClass = {
someProperty: function(){
//do something
},
anotherProperty: function(){
//doing something else
}
};
This is pretty much what everyone else is saying. I'm just giving the really simplistic approach. Main drawback I see is that theoretically the "MyNameSpace" object could already exist - so might want to check that before you create it. Generally, if I'm going to be doing anything more complicated than that I would start thinking of a framework like JQuery or ExtJS which take a lot of pain out of these sort of things.
One more note. Part of the reason why you can't find a common way to do many things in Javascript, like creating namespaces, is that there is always more than one way to skin a cat in Javascript. Most languages are quite proscriptive on how you do things - create classes, are functional or object oriented or procedural. Javascript, on the other hand, is short of keywords and highly flexible. This maybe a good thing or a bad thing - depending on your point of view. But I quite like it.
To share code between scripts, you have to have at least one global variable (unless of course if you would want to do something as silly as appending your variables to an already existing object such as window.Object.
Even if you use the module pattern, you need to have a common place to share code, so, say e.g. you have three scripts:
core.js
utils.js
Then we can in the core.js script file have a module:
(function(global) {
var coreModule = {};
var MY_CONSTANT = 42
var meaningOfLife = function() {
return MY_CONSTANT;
};
coreModule.meaningOfLife = meaningOfLife;
global.myRootNamespace = coreModule;
}(this));
in the utils.js:
(function(root) {
var utilsModule = root.utils = {};
utilsModule.bark = function() {
console.log("WOOF!");
};
}(myRootNamespace));
Here, we see the use of the augmentation module pattern, and namespacing the functionality depending on the nature of the functionality. This specific implementation overwrites the value of the utils property on the myRootNamespace object. However, we can write it so that it does not:
(function(root) {
var utilsModule = root.utils = root.utils || {};
utilsModule.bark = function() {
console.log("WOOF!");
};
}(myRootNamespace));
If one doesn't want to use the module pattern, we can use a simple function to define namespaces for us in a non destructive manner:
var ensureNamespace = function recur(ns, root) {
var parts = typeof ns === 'string' ? ns.split('.') : ns;
var r = root || this;
if (parts[0]) {
var next = parts.shift()
r[next] = r[next] || {};
return recur(parts, r[next]);
}
return r;
};
// maybe another file:
(function(){
var baz = ensureNamespace("foo.bar.baz");
// baz === window.foo.bar.baz;
baz.qux = "Yep...";
}());
see this excellent article for more insight.
You can combine the answers you have received so far and accomplish much;
var Foo; // declare in window scope.
(function(){
var privateVar = "BAR!";
// define in scope of closure where you can make a mess that
// doesn't leak into the window scope.
Foo = {
staticFunc: function(){ return privateVar; }
};
})();
I generally avoid window.xxxx = yyyy; as it does not always play nicely with visual studio intellesense. There may be other issues but none that I know of.
I believe the module pattern has shown that it is the way to go. Object Literal Name-spacing exposes everything to the caller code outside the namespace which is essentially not a very good idea.
If you insist on creating Object Literal Namespaces, read this tutorial. I find it easy and short and I believe is very through:Object Literal Namespace (OLN) in Javascript
Related
I have been reading a few different Javascript authors and each has their preferred way to declare properties on objects. None of the authors really explains the difference between these different ways. What are the differences and which way is the preferred declaration to us?
var One = function() {
var self = this;
self.foo = function() {};
return self;
}
var two = function() {
foo: function() {}
};
var three = function() {
var _foo = function() {};
three.foo = _foo;
}
tl;dr - See conclusion
Introduction
Declaring objects in javascript can be done many different ways, and from my point of view it all depends on how complex your project is.
The examples you proposed would be ways to declare variables within a complex project. You could even say for project maintainability and code quality the examples you proposed can be very interesting.
Part 1 - First example
Your first example you proposed was this function.
var One = function(){
var self = this;
self.foo = function(){};
return self;
}
Context: Global -> One()
Suppose we don't create an instance of One (not using new) This function has two objectives.
Attach the foo function to its parents context (usually window object = globally)
Return foo function
You could say you're killing two birds with one stone. While doing two things at once can be interesting, in the end it could really become a context problem.
Context is pretty much asking yourself, what does this refer to? Non instantiated functions inherit the parents context which is fine if none of those parents are instantiated themselves. If this is the case (meaning this != window object) and your primary goal was to attach foo globally well it just won't work.
Context: Self -> new One()
If you call this function with new, this will be different. this will refer to an instance of One. This is a lot more logical way.
In the end you could say that an instance of One will feel almost like an object.
Comparing with objects
I say almost mainly because what is the difference if One was:
var One_object = {
foo: function(){}
}
Well there isn't really, except you'll be more flexible with an object rather than an instance of a function.
//This will not work.
var a = new One();
a.titi = function(){
alert('titi');
}
//This will work
One_object.titi = function(){
alert('titi');
}
Improving the example
The only way that One as an instance can become interesting is if you declare multiple instances. Performance wise and memory wise it'll be more interesting.
var One = function(foo){
//auto instantiate it's self
if(!(this instanceof One)){
return new One(foo);
}
this.foo = foo || function(){};
}
Creating multiple instances of One with the same function probably defeats the purpose, so here is an example of how you could improve One.
var a = One(function(){
alert('instance one');
});
var b = One(function(){
alert('instance two');
});
Part 2 - Second example
var two = function() {
foo: function() {}l
};
Is actually wrong as I'm sure you've noticed from the comments. It should be instead:
var two = {
foo: function() {}
};
Where two is in fact an object and not a function.
This way of declaring variables/functions ensures that you are not overriding on a global scope any other function named "foo".
This can be very useful when you have a lot of js and you are declaring a lot of variables.
In this case, to access foo you need to simply call two.foo();
This is honestly my preferred way of declaring variables.
Variables are not scattered all across the js file.
They do not override any existing variables with the same name
It's clean and maintainable.
They can easily be moved around.
With this in mind, here is an example:
var options = {
foo: function(){
console.log('This is foo');
},
toto: function(){
console.log('This is titi');
}
};
var example = function(options){
options.foo();
options.toto();
}
example(options);
Part 3 - Barbaric
var three = function() {
var _foo = function() {};
three.foo = _foo;
}
A good standard when writing code is to keep the code readable. While this may work, it's not good practice. The main issue with writing Javascript is that it can easily become unreadable.. And in this case it feels barbaric (personal opinion).
Conclusion
As you've probably noticed example two is my preferred way (and to many others I know) in declaring Objects for the following reasons:
Structured
Organized
Easy to handle
Easy to maintain
Flexibility
No conflicts
Feel free to point out on anything I've missed.
In JavaScript you can declare "Objects" via several ways. The most easy way is:
var myObject = {}
from here on, adding methods or attributes is very easy as well:
myObject.myFirstMethod = function(){};
myObject.myFirstAttr = true;
myObject.mySecondAttr = "hello world!";
in this case, you would add those functions and attributes to your "myObject" Object. But there is a better and much cleaner way to do such stuff:
var myObject = function();
myObject.prototype.method1 = function(){};
myObject.prototype.method2 = functiion(){};
myObject.prototype.attr1 = true;
myObject.prototype.attr2 = "hello world!";
myObject.prototype.setAttr1 = function(value){
this.attr1 = value;
}
myObject.prototype.setAttr2 = function(value){
this.attr2 = value;
}
if you declared your Object this way, you can use
var myObjectInstance = new myObject();
this Object now has got every methods and attributes which you had defined in your prototype. more about prototypes:
http://www.w3schools.com/js/js_object_prototypes.asp
edit:
note that "this" in JavaScript means the "element", what called the actual method and NOT the object itself in any case...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
Is there anything in javascript that is the equivalent of java static imports? For example, if I have a Math class that looks like
com.example.Math = function() {
function1(...) {}
function2(...) {}
}
Now some of these functions are naturally chained together such that the output to one is the input to another. I can do something like
com.example.Math.function2(com.example.Math.function1());
This is a little ugly looking, and I would really like to do something like:
function2(function1())
But I don't want to put function1 and function2 in the global namespace. Is this possible?
Yes, there is. It's called with.
with (com.example.Math) {
function2(function1());
}
That said:
Using with is not recommended, and is forbidden in ECMAScript 5 strict mode. The recommended alternative is to assign the object whose properties you want to access to a temporary variable.
For example:
var m = com.example.Math;
m.function2(m.function1());
How about:
var Math = com.example.Math;
and then:
Math.fn1( Math.fn2(...) );
I'm assuming of course that your code is not global code. (If you're not familiar with the concept of avoiding global code in JS, read about the module pattern.)
You can go one step further:
var Math = com.example.Math,
func1 = Math.func1,
func2 = Math.func2;
and then:
func1( func2(...) );
I would do something like this:
var O = function() {
var that = {};
var PI = Math.PI;
that.circ = function(r) {
return 2*PI*r;
};
return that;
};
var o = O();
console.log(o.circ(1));
Notice how PI is used without the Math namespace in the O.prototype.circ method.
In JavaScript, there is no distinction between a namespace and an object, so some would argue that Math is not a namespace, but since JavaScript doesn't support the concept, it is as much a namespace as com.mycompany.somelibrary.
One option is to use a closure to wrap the object. It doesn't necessarily eliminate the object itself, but it helps with readability and if you are using a JS compressor can help reduce the output file size:
(function(Math) {
Math.function2(Math.function1(...));
}(com.example.Math);)
You can also pass in multiple objects (ie: function(Math, Foo) {...}(com.example.Math, com.example.Foo)).
If you want to use just a few functions directly, just pass them in like this:
(function(function1, function2) {
function2(function1(...));
}(com.example.Math.function1, com.example.Math.function2);)
This, however, removes the relationship between the Math instance and the functions, so you might get some weird behavior if your methods depend on instance variables. As an example of how that won't work, imagine this class:
com.example.Counter = {
counter: 0,
increment: function() { this.counter++; }
}
We have a lot of setup JS code that defines panels, buttons, etc that will be used in many other JS files.
Typically, we do something like:
grid.js
var myGrid = .....
combos.js
var myCombo = .....
Then, in our application code, we:
application.js
function blah() {
myGrid.someMethod()
}
someother.js
function foo() {
myCombo.someMethod();
myGrid.someMethod();
}
So, should we be using the var myGrid or is better to use window.myGrid
What's the difference?
A potentially important difference in functionality is that window.myGrid can be deleted, and var myGrid can not.
var test1 = 'value';
window.test2 = 'value';
console.log( delete window.test1 ); // false ( was not deleted )
console.log( delete window.test2 ); // true ( was deleted )
console.log( test1 ); // 'value' ( still accessible )
console.log( test2 ); // ReferenceError ( no longer exists )
I would suggest creating a namespace variable var App = {};
App.myGrid = ...
That way you can limit the pollution of the global namespace.
EDIT: Regarding the number of variables issue - 2 possible solutions come to mind:
You can further namespace them by type(Grids, Buttons, etc) or by relationship(ClientInfoSection, AddressSection, etc)
You encapsulate your methods in objects that get instantiated with the components you have
ex: you have
function foo() {
myCombo.someMethod();
myGrid.someMethod();
}
becomes:
var Foo = function(combo, grid) {
var myCombo = combo;//will be a private property
this.myGrid = grid;//will be a public property
this.foo = function() {//public method
myCombo.someMethod();
myGrid.someMethod();
}
}
App.myFoo = new Foo(someCombo, someGrid);
App.myFoo.foo();
this way you limit the amount of little objects and only expose what you need (namely the foo function)
PS: if you need to expose the internal components then add them to this inside the constructor function
One nice use of window.variable is that you can check it without having a javascript error. For example, if you have:
if (myVar) {
//do work
}
and myVar is not defined anywhere on the page, you will get a javascript error. However:
if (window.myVar) {
//do work
}
gives no error, and works as one would expect.
var myVar = 'test' and window.myVar = 'test' are roughly equivalent.
Aside from that, as other said, you should descend from one global object to avoid polluting the global namespace.
In global scope the two are in fact equivalent functionality-wise. In function scope, var is certainly preferable when the behaviour of closures is desired.
I would just use var all of the time: firstly, it's consistent with the usually preferred behaviour in closures (so it's easier to move your code into a closure if you decide to do so later), and secondly, it just feels more semantic to me to say that I'm creating a variable than attaching a property of the window. But it's mostly style at this point.
The general answer to the question would be to use var.
More specifically, always put your code in an Immediately Invoked Function Expression (IIFE):
(function(){
var foo,
bar;
...code...
})();
This keeps variables like foo and bar from polluting the global namespace. Then, when you explicitly want a variable to be on the global object (typically window) you can write:
window.foo = foo;
JavaScript has functional scope, and it's really good to take full advantage of it. You wouldn't want your app to break just because some other programmer did something silly like overwrote your timer handle.
In addition to other answers, worth noting is that if you don't use var inside a function while declaring a variable, it leaks into global scope automatically making it a property of window object (or global scope).
To expand on what Liviu said, use:
App = (function() {
var exports = {};
/* code goes here, attach to exports to create Public API */
return exports;
})();
By doing that you can hide some of your implementation specific code, which you may not want exposed by using var's inside. However, you can access anything attached to the exports object.
This question already has answers here:
Why use the javascript function wrapper (added in coffeescript) ".call(this)"
(2 answers)
Closed 8 years ago.
While reviewing the source code for CoffeeScript on Github, I noticed that most, if not all, of the modules are defined as follows:
(function() {
...
}).call(this);
This pattern looks like it wraps the entire module in an anonymous function and calls itself.
What are the pros (and cons) of this approach? Are there other ways to accomplish the same goals?
Harmen's answer is quite good, but let me elaborate a bit on where this is done by the CoffeeScript compiler and why.
When you compile something with coffee -c foo.coffee, you will always get a foo.js that looks like this:
(function() {
...
}).call(this);
Why is that? Well, suppose you put an assignment like
x = 'stringy string'
in foo.coffee. When it sees that, the compiler asks: Does x already exist in this scope, or an outer scope? If not, it puts a var x declaration at the top of that scope in the JavaScript output.
Now suppose you write
x = 42
in bar.coffee, compile both, and concatenate foo.js with bar.js for deployment. You'll get
(function() {
var x;
x = 'stringy string';
...
}).call(this);
(function() {
var x;
x = 42;
...
}).call(this);
So the x in foo.coffee and the x in bar.coffee are totally isolated from one another. This is an important part of CoffeeScript: Variables never leak from one .coffee file to another unless explicitly exported (by being attached to a shared global, or to exports in Node.js).
You can override this by using the -b ("bare") flag to coffee, but this should only be used in very special cases. If you used it with the above example, the output you'd get would be
var x;
x = 'stringy string';
...
var x;
x = 42;
...
This could have dire consequences. To test this yourself, try adding setTimeout (-> alert x), 1 in foo.coffee. And note that you don't have to concatenate the two JS files yourself—if you use two separate <script> tags to include them on a page, they still effectively run as one file.
By isolating the scopes of different modules, the CoffeeScript compiler saves you from the headache of worrying whether different files in your project might use the same local variable names. This is common practice in the JavaScript world (see, for instance, the jQuery source, or just about any jQuery plugin)—CoffeeScript just takes care of it for you.
The good thing about this approach is that it creates private variables, so there won't be any conflict with variable names:
(function() {
var privateVar = 'test';
alert(privateVar); // test
})();
alert(typeof privateVar); // undefined
The addition of .call(this) makes the this keyword refer to the same value as it referred to outside the function. If it is not added, the this keyword will automatically refer to the global object.
A small example to show the difference follows:
function coffee(){
this.val = 'test';
this.module = (function(){
return this.val;
}).call(this);
}
var instance = new coffee();
alert(instance.module); // test
function coffee(){
this.val = 'test';
this.module = (function(){
return this.val;
})();
}
var instance = new coffee();
alert(typeof instance.module); // undefined
This is similar syntax to this:
(function() {
}());
which is called an immediate function. the function is defined and executed immediately. the pros to this is that you can place all of your code inside this block, and assign the function to a single global variable, thus reducing global namespace pollution. it provides a nice contained scope within the function.
This is the typical pattern i use when writing a module:
var MY_MODULE = (function() {
//local variables
var variable1,
variable2,
_self = {},
etc
// public API
_self = {
someMethod: function () {
}
}
return _self;
}());
not sure what the cons might be exactly, if someone else knows of any i would be happy to learn about them.
I was looking over the js source code for Scrabb.ly.
I've noticed that they would do something like so for each of their distinct "classes":
var Board = (function() {
var self = {};
// settings for board
self.options = {
debug: true,
addedPlayTiles: function() {},
clearedPlayTiles: function() {}
};
// set to true once the board has been setup
self.isSetup = false;
// quick access to square elements
self.squares = {};
self.squareCount = 0;
self.setup = function(options) {
self.log("Setting up board!");
// set options
_.each(options, function(val, key) {
self.options[key] = val;
});
return self;
})();
Some code from the middle has been omitted but this should give you the general idea.
What is the purpose of the the following: (function() { // code })(); Is this the module pattern that I've seen talked about? Is this meant to keep the global namespace clean?
What does this line mean?: var self = {} Is the self object used to exposed 'public' members? How would you define a private function or variable?
How would you instantiate multiple "Boards" if you wanted to?
It's called the Module Pattern.
The parentheses around the function mean it's being evaluated immediately after being defined -- so in essence it's a Singleton. Since it's an anonymous function, the definition is not stored - so you cannot readily create new instances of this object without a few modifications (which will be discussed later).
You are correct, self contains the "public" methods and properties, as it were. Any variables that aren't defined in self are not visible to the outside because of the closure properties. However, any functions defined in self still have access to the private variables because in Javascript, functions maintain access to the context (including variables) in which they were defined -- with a few exceptions.. mainly arguments and this.
If you want to define multiple instances of this object, you would remove the parentheses (var Board = function () { ... }) and then use var obj = Board() to create an object. Note that it does not use the new operator.
As mentioned in the other answer, that's the Module Pattern.
It is also known as the YUI Module Pattern or the Yahoo Module Pattern, mainly because it was made popular by this blog article:
YUI Blog: A JavaScript Module Pattern by Eric Miraglia
Regarding point 3, the Module Pattern is intended to be a singleton. However, the Module Pattern is easily transformed into a Constructor Pattern. You may want to check out the following presentation by Douglas Crockford for more information on this topic:
JavaScript: The Good Parts - Functional Inheritance [PPT] by Douglas Crockford
var self = {} should have the effect of initializing self as an empty object literal; if self already existed, it should delete the old values and reinitialize as an empty array.