JavaScript has no “Class” concept in the mainstream OOP point of view. You don’t define a “class” and instance objects that are a “phisical” representation of that. Technically, JavaScript is a “prototype based” language. This brings some nice things but also makes all the “object programming” experience in JavaScript full of traps, misunderstandings and weirdness…
This little series of articles (2 or 3) is my personal attempt to clear this mess a little. A lot of other “JavaScript object programming tutorial” yet exist, and surely many of them are more technically accurate then mine. I only hope to put this problem into a more “human friendly” point of view.
Let me begin with a very simple example: from one point of view, you can think of objects in JavaScript as they were simple “containers”. You aggregate functions (methods), and variables (properties) under the same umbrella. You may or MAY NOT give that umbrella a real handle (name) to work with it. Let’s walk through this:
var one_object = {};
This creates an “anonymous” empty object and assigns it to the “one_object” variable.
Now “one_object” can really behave like an object. As you may know, you can for example brutally add properties to it:
var one_object = {};
one_object.property_one="Hello";
one_object.property_two="World";
You can even add methods:
one_object.method_one = function() {
alert(this.property_one)
}
one_object.method_two = function() {
alert(this.property_two)
}
Very simple and straightforward. You have the “one_object” umbrella that you can use as a… NAMESPACE. Put everything into it, without the fear of potential name clashes (and you always should).
What I’d like to note here is that “one_object” is the one and only representative of its species… There’re no other way to instantiate another object with the same characteristics (yes, you could COPY the object itself; but it is not a creational process the way OO learned to us). We have USED and MODIFIED/extended a real object, not a “class”.
By the way, you should know that just another syntax exists to create an object that way:
var one_object = {
property_one: "Hello",
property_one: "World",
method_one: function() {
alert(this.property_one)
},
method_two: function() {
alert(this.property_two)
}
};
You can pass “anonymous” objects as a parameter to a function:
killZombies({weapon: "flame thrower", power_level: 4});
A step further
But, what is exactly a “{}”?
{} is a shortcut for “new Object()” and…
“Wait wait wait!”, I hear you, “there’s a NEW construct there! So, Object is CLASS, ah-ah!”
OK, spotted… the “new” construct it’s really something that could confuse. Let me start from the beginning…
As I said, objects are elements that are ready to use with no big fuss (a pair of {}), but this is true only when you need the more generic object possible (a container, remember?). But you might need to create a MODEL for an object so that you can create instances of it, at your will. Do you need many Cars? Build a generic Car object and then replicate it for every Car you’ll need.
We have then to move away from the simple “objects are containers surrounded by {}” model, and think of a way to build a generic, specialized model to replicate at our will. The key, here, is the word CONSTRUCTOR. For every custom objects you’re about to create, you have to FIRST create the constructor. In a Class oriented object model, the constructor is part of the class… in JavaScript, the constructor IS the object.
Sintactically, a constructor is only a function, and its name will name the object too.
Speaking of cars, we could write the simplest constructor ever:
function Car() {
}
(I use the capital C just for convention: JavaScript give no meaning to the case of variable names; but it’s case sensitive)
OK. So how can I create an object that is a copy of a Car? Use the “new” keyword and call the constructor:
function Car() {
}
var car = new Car();
In this oversimplified and useless example, we are telling JavaScript: “Listen, I need an object that I’d like to name ‘car’. Build it calling the Car() function”.
But isn’t Car() a “normal” function? Yes, it is. Indeed, it’s the context in which you use it that differentiate its… function. Let’s see:
Everyone knows that in an OOP world, “this” (or “self”) represents the current instance of a class, inside its definition. Let’s use “this” to show the aforementioned behaviour:
function Car() {
alert(this);
}
var car = new Car()
Car();
In this example, we try to see what “this” is, first calling the function as the constructor of a car, then calling the function by itself. If you run this example, you’ll see first an “object Object” and then an “object Window”.
If you use Car() as a constructor “this” is an instance of an Object (namely Car), while calling it by itself it will be an instance of a Window object.
Interesting. This experiment will lead us to the following conclusion (so far):
- every object YOU create, will always descend from the root object “Object”
- JavaScript is not aware of the name of the object YOU create, and will say it’s simply an Object copy
- every function belongs to an outer, big object that is a copy of a Window object (that is the “window” object itself, of course, and it will descend from the Object too)
Let’s do something more useful, adding a property and a method to our simple Car:
function Car(color) {
this.color = color;
this.run = function() {
alert("Global warming++");
}
}
var car1 = new Car('red')
var car2 = new Car('blu')
var car3 = new Car('green')
Nothing really strange here; you can see how to pass a parameter to the contructor and using it. We then create 3 object all of the same type. In the constructor we are defining the characteristics of the Car model, adding something to “this”…
And this is enough for this first part of the discussion about JavaScript model. What we’ll see next will be a more seriuos definition of the “descend” word I used, and some advanced tecnique you may have sometimes seen but you were too afraid to ask :)
RSS






