How do I declare a namespace in JavaScript?
I like this:
var yourNamespace = {
foo: function() {
},
bar: function() {
}
};
...
yourNamespace.foo();
JavaScript Namespace Declaration
Usually I'd recommend doing this (assuming Namespace
is not defined elsewhere):
var Namespace = {};
Namespace.MyClass = (function () {
// ...
}());
A more flexible, but more complex, approach:
var Namespace = (function (Namespace) {
Namespace.MyClass = function() {
var privateMember = "private";
function myPrivateMethod(param) {
alert(param || privateMember);
};
MyClass.MyPublicMember = "public";
MyClass.MyPublicMethod = function (param) {
myPrivateMethod(param);
};
}
return Namespace
}(Namespace || {}));
This builds Namespace.MyClass
as above, but doesn't rely on Namespace
already existing. It will declare and create it if it does not already exist. This also lets you load multiple members of Namespace
in parallel in different files, loading order will not matter.
For more: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
Define a class with namespace in Javascript
You can just create a new object that contains all your classes/functions:
var myNamespace = {};
myNamespace.Person = function (name, gender) {
// Add object properties like this
this.name = name;
this.gender = gender;
}
myNamespace.Person.prototype.speak = function() {
alert("Howdy, my name is" + this.name);
}
// Instantiate new objects with 'new'
var person = new myNamespace.Person("Bob", "M");
// Invoke methods like this
person.speak(); // alerts "Howdy, my name is Bob"
MDN has an article explaining JavaScript namespacing.
How to declare a namespace in JavaScript ECS6
In ES2015+, in the main you don't need these fake namespaces anymore. Instead, use modules. (Perhaps with a module loader, since native support for modules is still only just making its way into browsers.)
But if you want to continue using fake namespaces, perhaps temporarily until native support for modules becomes more widespread, what you have is fine, though there's no real advantage to Foo
being declared with class
than just making it an object as in your original example:
var Foo = Foo || {};
Foo.Bar = class Bar{
constructor(){
this.stuff = null;
}
get moreStuff(){ return this.stuff++;}
do(){...}
};
But your version is fine other than giving the impression that Foo
can be used to construct something useful, and other than the fact that if you do that in two files, it will fail (whereas your first example using var foo = foo || {};
is happy for you to do that in two files and include them both on the same page, perhaps one definign foo.Something
and another defining foo.SomethingElse
).
JavaScript namespace object literal
Although ||
was originally intended to work with booleans, it is implemented in a very handy way that allows it to work to set default values:
function or(a, b) {
if (a) return a
else return b
}
You can test this in your head and see that it works with booleans: if a
is true
, the result is true
so the result is the same as a
. If a
is false
then the result depends on b
.
Variable declarations with var
in JavaScript work a bit strangely. You are allowed to redeclare a variable with the same identifier in the same scope. So the way the code works is:
- If
myNamespace
is already declared, you redeclare the variable without assigning to it yet. You get the value from the old declaration ofmyNamespace
. This value is assumed to be truthy, so the||
will return it. - If
myNamespace
is not yet declared, you declare it and thenmyNamespace
will beundefined
, a falsy value. So the||
will return the second value, the{}
, and that is the value that will get assigned tomyNamespace
.
It may make sense to read it in two separate steps:
//Declare the variable if it doesn't exist,
//without overwriting an existing value
var myNamespace
//Take the value of myNamespace (undefined if it didn't exist yet)
//and replace it with {} if it is falsy
myNamespace = myNamespace || {}
How to create a top level namespace in javascript
First of all: there are no namespaces in JavaScript. You can somewhat simulate namespaces using objects.
First you have to make sure that your todo
object does exist. (You cannot bulk-create properties)
window.todo = {};
Then you can add properties to that todo
object:
window.todo.item = (function () { ... })();
// or
window.todo.item = item;
You can also initialize properties while creating the todo
object:
window.todo = {
item: (function { ... })()
};
// or
window.todo = {
item: item
};
Safely creating namespaces in JavaScript
What will happen is that your aplication will overwrite the properties of the previous one or viceversa depending on wich is executed first.
In javascript "almost" everything can be overwriten. Your aplication is just a simple object in global scope so if the other aplication is written like this.
var MYAPPLICATION = {};
MYAPPLICATION.foo = function () {....}
And yours is
var MYAPPLICATION = MYAPPLICATION || {};
MYAPPLICATION.bar = function () {...}
You will end up with a global variable called MYAPPLICATION with two properties 'foo' and 'bar' with functions defined on it.
One will be yours and the other is not so you can end up with unespected behaviour of your code. So in other words there is no really a safe way of create a namespace in javascript.
You can check this SO article Is there a "concise" way to do namespacing in JavaScript? for more information but I personally recommend you that you use the sandbox pattern instead. This will help you isolate your code a little better.
This is post contains an example to get you started. This adresses some problems of the namespace pattern like having multiple versions of the same app and long name resolution like app.module.foo.bar.daa.
How to set up JavaScript namespace and classes properly?
Do neither of those things.
Make a javascript "class":
var MyClass = function () {
var privateVar; //private
var privateFn = function(){}; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
MyNamespace.MyClass = new MyClass();
One with static vars:
var MyClass = (function(){
var static_var; //static private var
var MyClass = function () {
var privateVar; //private
var privateFn = function(){}; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
return MyClass;
})();
MyNamespace.MyClass = new MyClass();
With a "constructor" (all of the examples have a "constructor", this one just has parameters to work with):
var MyClass = function (a, b c) {
//DO SOMETHING WITH a, b, c <--
var privateVar; //private
var privateFn = function(){}; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
MyNamespace.MyClass = new MyClass(1, 3, 4);
With all of the above you can do:
MyNamespace.MyClass.someFunction();
But you cannot do (from the outside):
MyNamespace.MyClass.privateFn(); //ERROR!
Related Topics
Convert Form Data to JavaScript Object With Jquery
How to Add a Delay in a JavaScript Loop
What Is the 'New' Keyword in JavaScript
How to Return Many Promises and Wait For Them All Before Doing Other Stuff
What Does the Comma Operator Do in JavaScript
How to Use the : (Conditional) Operator in JavaScript
When Should I Use Curly Braces For Es6 Import
Getting the Client'S Time Zone (And Offset) in JavaScript
What Is the Purpose of Node.Js Module.Exports and How to Use It
Rails 4: How to Use $(Document).Ready() With Turbo-Links
Generate Random Number Between Two Numbers in JavaScript
Explanation of 'Let' and Block Scoping With For Loops
How to Convert a String to Boolean in JavaScript
++Somevariable Vs. Somevariable++ in JavaScript
Passing Data Between Controllers in Angular Js
Can You Bind 'This' in an Arrow Function