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 />

In this example, the Person constructor assigns three properties using the this object: name , age , and<br />

job . When used with the new operator, a new Person object is created, and the properties are assigned<br />

onto it. The problem occurs when the constructor is called without the new operator. Since the this<br />

object is bound at runtime, calling Person() directly maps this to the global object ( window ), resulting<br />

in accidental augmentation of the wrong object. For example:<br />

var person = Person(“Nicholas”, 29, “Software Engineer”);<br />

alert(window.name); //”Nicholas”<br />

alert(window.age); //29<br />

alert(window.job); //”Software Engineer”<br />

Here, the window object has been augmented with the three properties intended for a Person<br />

instance, because the constructor was called as a regular function, omitting the new operator. This<br />

issue occurs as a result of late binding of the this object, which was resolved to window in this case.<br />

Since the name property of window is used to identify link targets as well as frames, this accidental<br />

overwriting of the property could lead to other errors on the page. The solution is to create a<br />

scope - safe constructor.<br />

Scope - safe constructors first check to ensure that the this object is an instance of the correct type before<br />

applying any changes. If not, then a new instance is created and returned. Consider this example:<br />

function Person(name, age, job){<br />

if (this instanceof Person){<br />

this.name = name;<br />

this.age = age;<br />

this.job = job;<br />

} else {<br />

return new Person(name, age, job);<br />

}<br />

}<br />

var person1 = Person(“Nicholas”, 29, “Software Engineer”);<br />

alert(window.name); //””<br />

alert(person1.name); //”Nicholas”<br />

var person2 = new Person(“Shelby”, 34, “Ergonomist”);<br />

alert(person2.name); //”Shelby”<br />

The Person constructor in this code adds an if statement that checks to ensure that the this object is<br />

an instance of Person , which indicates that either the new operator was used or the constructor was<br />

called in the context of an existing Person instance. In either case, the object initialization continues as<br />

usual. If this is not an instance of Person , then the constructor is called again with the new operator<br />

and that value is returned. The result is that calling the Person constructor either with or without the<br />

new operator returns a new instance of Person , avoiding any accidental property setting on the<br />

global object.<br />

590

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

Saved successfully!

Ooh no, something went wrong!