As an OO language, pre-ECMAScript-6 JavaScript is classless, meaning that we cannot define a
class Point the way we did in the previous section.
And yet, pre-ECMAScript-6 JavaScript
allows us to work with points much the same way we did in the traditional, class-based
environments. To achieve this, we must first define a constructor function for points.
All we need to do in the body of this constructor function is to name and initialize
the fields (member variables) that we want for our point:
function Point(x, y) { this.x = x; this.y = y; }We can now create a point like this: var p = new Point(0.0, 0.0);When the function Point is called in this manner, with the new operator,
it is interpreted as a constructor.
That means that the following happens inside the function call:
this.x = x; this.y = y;in the body of the constructor function automatically add the properties x and y
to the new object1. In view of this, it is quite plausible that
pre-ECMAScript-6 JavaScript did not need classes: if the initialization of a field in the constructor brings
that field into existence, then there is no need to declare it elsewhere.
We can now create point objects and work with their coordinates, like this: var p = new Point(0.0, 0.0); p.x = 42.0;Borrowing terminology from class-based languages, JavaScript objects that are created in this manner are often called Point instances, or instantiations of Point .
As you can see, the fields of
In order to complete our transition from the
Before we continue, one more word on JavaScript's constructor functions is in order.
Constructor functions behave like constructors only if they're called with the
var p = new Point(0.0, 0.0);It is entirely possible to call a constructor function in any other way, like // Bad var p = Point(0.0, 0.0);The effect of that, of course, is non-sensical. No object is created, undefined is returned,
and, perhaps worst of all, this is bound to the global object, resulting in properties
x and y being added to the global object. The fact that a constructor can be
called in this way, as a “non-constructor,” may seem like an oversight or a bug in the language.
However, we will see in Section 7 that calling constructor
functions without the new operator is needed to implement inheritance.
If the danger of calling a constructor function erroneosly as
a “non-constructor” bothers you, then Item 33 of David Herman's
Effective JavaScript
has some advice for you.
1This is true not only in constructor functions. In JavaScript, or in any dynamic OO language,
for that matter, whenever you have an object
o
that does not currently have a property named x , then the line
o.x = 42;will add the property x to the object o .
|