HTML and CSS Reference
In-Depth Information
By not overwriting the
prototype
property, we are also avoiding its
constructor
property being enumerable. The object provided for us has the
DontEnum
attribute set, which is impossible to recreate when we assign a cus-
tom object to the
prototype
property and manually restore the
constructor
property.
7.2.4 The Problem with Constructors
There is a potential problem with constructors. Because there is nothing that sep-
arates a constructor from a function, there is no guarantee that someone won't use
your constructor as a function. Listing 7.23 shows how a missing
new
keyword can
have grave effects.
Listing 7.23
Constructor misuse
"test calling prototype without 'new' returns undefined":
function () {
var circle = Circle(6);
assertEquals("undefined", typeof circle);
// Oops! Defined property on global object
assertEquals(6, radius);
}
This example shows two rather severe consequences of calling the constructor
as a function. Because the constructor does not have a return statement, the type of
the
circle
ends up being
undefined
. Even worse, because we did not call the
function with the
new
operator, JavaScript did not create a new object and set it as
the function's
this
value for us. Thus, the function executes on the global object,
causing
this.radius = radius
to set a
radius
property on the global object,
as shown by the second assertion in Listing 7.23.
In Listing 7.24 the problem is mitigated by use of the
instanceof
operator.
Listing 7.24
Detecting constructor misuse
function Circle(radius) {
if (!(this instanceof Circle)) {
return new Circle(radius);
}
this.radius = radius;
}