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.

Respect Object Ownership<br />

Chapter 20: Best Practices<br />

The dynamic nature of JavaScript means that almost anything can be modified at any point in time. It ’ s<br />

been said that nothing in JavaScript is sacred, as you ’ re unable to mark something as final or constant. In<br />

other languages, objects and classes are immutable when you don ’ t have the actual source code.<br />

JavaScript allows you to modify any object at any time, making it possible to override default behaviors<br />

in unanticipated ways. Because the language doesn ’ t impose limits, it ’ s important and necessary for<br />

developers to do so.<br />

Perhaps the most important programming practice in an enterprise environment is to respect object<br />

ownership, which means that you don ’ t modify objects that don ’ t belong to you. Put simply: if you ’ re<br />

not responsible for the maintenance of an object, its constructor, or its methods, you shouldn ’ t be making<br />

changes to them. More specifically:<br />

❑<br />

❑<br />

❑<br />

Don ’ t add properties to instances or prototypes.<br />

Don ’ t add methods to instances or prototypes.<br />

Don ’ t redefine existing methods.<br />

The problem is that developers assume that the browser environment works in a certain way. Changes to<br />

objects that are used by multiple people mean that errors will occur. If someone expects a function called<br />

stopEvent() to cancel the default behavior for an event, and you change it so it does that and also<br />

attaches other event handlers, it is certain that problems will follow. Other developers are assuming that<br />

the function just does what it did originally, so their usage will be incorrect and possibly harmful<br />

because they don ’ t know the side effects.<br />

These rules apply not only to custom types and objects, but also to native types and objects such as<br />

Object , String , document , window , and so on. The potential issues here are even more perilous<br />

because browser vendors may change these objects in unannounced and unanticipated ways. An<br />

example of this occurred in the popular Prototype JavaScript library, which implemented the<br />

getElementsByClassName() method on the document object, returning an instance of Array that had<br />

also been augmented to include a method called each() . John Resig outlined the sequence of events that<br />

caused the issue on his blog. In his post, he noted that the problem occurred when browsers began to<br />

natively implement getElementsByClassName() , which does not return an Array but rather a<br />

NodeList that doesn ’ t have an each() method. Developers using the Prototype library had gotten used<br />

to writing code such as this:<br />

document.getElementsByClassName(“selected”).each(Element.hide);<br />

Although this code worked fine in browsers that didn ’ t implement getElementsByClassName()<br />

natively, it caused an error in the ones that did, as a result of the return value differences. You cannot<br />

anticipate how browser vendors will change native objects in the future, so modifying them in any way<br />

can lead to issues down the road when your implementation clashes with theirs.<br />

The best approach, therefore, is to never modify objects you don ’ t own. You can still create new<br />

functionality for objects by doing the following:<br />

❑<br />

❑<br />

Create a new object with the functionality you need, and let it interact with the object of interest.<br />

Create a custom type that inherits from the type you want to modify. You can then modify the<br />

custom type with the additional functionality.<br />

643

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

Saved successfully!

Ooh no, something went wrong!