DEV Community

Dima Kuzmich
Dima Kuzmich

Posted on • Originally published at Medium on

JavaScript Global Object, Namespaces and Object constructors

Global Object

A global object is an object that created once the application is running. We can’t recreate it or affect his creation in any way. After a creation Global Object uses as a global scope of the application. Actually, in JavaScript, we haven’t global variables and functions. All variables and functions that defined globally become properties of the Global Object. So, all variables in JavaScript are placed under the Global Object. ECMA-262 does not indicate a way to access the Global object directly, but we can implement the access to him by using this.

The example below shows you how to do it:

var globalObject = (function(){
 return this;
})();

Check it on jsFiddle

In web applications the browser implementation of ECMA-262 has an object called window that uses as a delegate to a Global Object, so all the way we can access him very simply:

var globalObject = window;

In the above examples, we created variables that hold a reference to the Global Object. As discussed previously, all global variables become properties of Global Object, so we simply created properties on Global Object that refer to themselves.

Because all new variables and functions are placed under the Global Object, there is a very high chance of name collision. As we know, JavaScript is loosely typed language and as such he is not preserving a type for created variables. So, all variables can overhead other variables just by using the same name. This is a name collision that we talked about before.

To prevent a name collision we can use a number of techniques such as using namespaces, using modules, and more.

Namespaces

Namespaces are objects that created under Global Object and hold variables and functions. Think about it like a tree. A tree has a root (Global object) and branches. Every branch is a new namespace.

Variables-tree

To implement it in JavaScript we use next code:

var myNamespace = myNamespace || {};

The left side of the example above simply declares a variable for our namespace. Right side a little bit more complicated. First of all, we try to get a namespace with the same name, if declared somewhere in the application. This technique prevents the recreation of the same namespace and not allow us to overhead his logic. Another pro of this technique is that we can use the same namespace in several files. Anyway, if a namespace was not declared before in application, we simply assign the variable with the empty object and thereby create a new namespace.

Object constructors

As we know in JavaScript we can create a new object in two ways. First way is to use the new keyword:

var rectangle = new Object();
rectangle.a = 10;
rectangle.b = 5;
rectangle.getPerimeter = function() {
 return 2\*(this.a + this.b);
}

Second way is to use object literal that is commonly used way. The big pro of this way is that you can encapsulate a creation of an object. The previous example can be rewritten as follows:

var rectangle = {
 a: 10,
 b: 5,
 getPerimeter: function() {
 return 2\*(this.a + this.b);
 }
}

Two ways above show us how to create a simple JavaScript object. It’s fine, but what if I want to create number of rectangles in my application? Do I need to duplicate that code for every rectangle instance? The answer, of course, is no. We can use a constructors. Two previous examples can be rewritten with constructor as follows:

function Rectangle(a, b) {
 this.a = a;
 this.b = b;
 this.getPerimeter = function() {
 return 2\*(this.a + this.b);
 };
}
var rectangle = new Rectangle(10,5);

Constructors in ECMAScript are used to create specific types of objects. Constructors provide us with the ability to create new object instances in a simple way. More of that, every instance created with a constructor can be identified which type is he.

function Rectangle(a, b) {
 this.a = a;
 this.b = b;
 this.getPerimeter = function() {
 return 2\*(this.a + this.b);
 };
}
var rectangle = new Rectangle(10,5);
alert(rectangle.constructor == Rectangle); // alerts true
alert(rectangle instanceof Rectangle); //alerts true

Try it in jsFiddle

The example above shows that we can identify the type of object in two ways. By checking his constructor property and by using instanceof operator. During object creation, the constructor property is automatically assigned with a reference to the constructor function. But the constructor is not placed on the object itself. It’s placed on a prototype of the object. We can check the object prototype by inspecting an object by Dev Tools or by accessing a __proto__ property of an object in Chrome, Safari, and Firefox.

So until now, we can understand 3 important things:

  1. All variables and functions are placed on the Global Object
  2. To prevent name collision we can use a namespaces
  3. We need to use a constructor to create specific types of objects

But when we look at constructors we can understand that it is just regular JavaScript function and as such, when placed on global scope, can be easily overwritten by another function with same name. So we will want to place it under namespace as well. It can look like follows:

var namespace = namespace || {};
namespace.Rectangle = function(a, b) {
 this.a = a;
 this.b = b;
 this.getPerimeter = function() {
 return 2\*(this.a + this.b);
 };
}
var rectangle = new namespace.Rectangle(10,5);

It’s good, but when we will expect a constructor of the rectangle, we will see that there is an anonymous function so the prototype will be of the regular Object type.

proto

What we want, is to be able with a namespace to look at prototype and to identify that this object is instance of Rectangle. I still can use instanceof operator and it’s smart enough to say me that is a Rectangle, but as a developer I will like to see it in my DevTools as well and to know that object prototype is Rectangle. To achieve that, we can use a next trick:

var namespace = namespace || {};
namespace.Rectangle = function <strong>Rectangle</strong>(a, b) {
 this.a = a;
 this.b = b;
 this.getPerimeter = function() {
 return 2\*(this.a + this.b);
 };
}
var rectangle = new namespace.Rectangle(10,5);

What I did is I simply gave the name to the constructor function. Now we can see that our object constructor is under namespace and we still can see that object prototype is Rectangle:

proto2

Using this way take care of IE <= 8.

Thanks


Discussion (0)