04.11.2015 Views

javascript

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 18: Advanced Techniques<br />

There is a caveat to scope - safe constructors. By implementing this pattern, you are locking down the<br />

context in which the constructor can be called. If you ’ re using the constructor - stealing pattern of<br />

inheritance without also using prototype chaining, your inheritance may break. Here is an example:<br />

function Polygon(sides){<br />

if (this instanceof Polygon) {<br />

this.sides = sides;<br />

this.getArea = function(){<br />

return 0;<br />

};<br />

} else {<br />

return new Polygon(sides);<br />

}<br />

}<br />

function Rectangle(width, height){<br />

Polygon.call(this, 2);<br />

this.width = width;<br />

this.height = height;<br />

this.getArea = function(){<br />

return this.width * this.height;<br />

};<br />

}<br />

var rect = new Rectangle(5, 10);<br />

alert(rect.sides); //undefined<br />

In this code, the Polygon constructor is scope - safe, whereas the Rectangle constructor is not. When a<br />

new instance of Rectangle is created, it should inherit the sides property from Polygon through the<br />

use of Polygon.call() . However, since the Polygon constructor is scope - safe, the this object is not an<br />

instance of Polygon , so a new Polygon object is created and returned. The this object in the Rectangle<br />

constructor is not augmented, and the value returned from Polygon.call() is not used, so there is no<br />

sides property on the Rectangle instance.<br />

This issue resolves itself if prototype chaining or parasitic combination is used with constructor stealing.<br />

Consider the following example:<br />

function Polygon(sides){<br />

if (this instanceof Polygon) {<br />

this.sides = sides;<br />

this.getArea = function(){<br />

return 0;<br />

};<br />

} else {<br />

return new Polygon(sides);<br />

}<br />

}<br />

function Rectangle(width, height){<br />

Polygon.call(this, 2);<br />

this.width = width;<br />

this.height = height;<br />

(continued)<br />

591

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!