Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Extending The JavaScript Date Object with User Defined Methods (digital-web.com)
5 points by maurycy on April 19, 2008 | hide | past | favorite | 7 comments


Boo! Hiss! When will folks learn that extending the prototypes of built-in JS classes is a bad, bad idea?

The problem comes when you try to build libraries on top of the extensions. You have your set of extensions to Date, somebody else has their set of extensions to Date (possibly with the same names), then two other folks each build libraries on top of those extensions. What happens when a poor app developer wants to use both libraries? Whose extensions win out?

Or what if the two library guys both just use your extensions, but in between library A's release and library B's release, you update the extensions with some subtle backwards-incompatible changes? One or both of the libraries will crash with unsatisfied dependencies.

Just say no. The right way to implement functionality like this is through a namespace object that holds a bunch of standalone functions. The namespace should expose only itself to the global namespace, and have a noConflict() method that restores the full state of the global environment on demand. Then any dependent libraries should close over the libraries they use, so that you can call noConflict after loading the dependent library and it'll use the bindings that were in effect at load time. There's a good example in the JQuery source code. It's a pain, it's cluttered, it's more verbose than pure prototype extension, but it ensures that your abstractions don't leak. You can be sure that adding a new JavaScript library won't suddenly break the libraries you're already using.


"The problem comes when you try to build libraries on top of the extensions. You have your set of extensions to Date, somebody else has their set of extensions to Date, then two other folks each build libraries on top of those extensions. What happens when a poor app developer wants to use both libraries? Whose extensions win out?"

How often does this actually happen with JavaScript projects, and why wouldn't unit tests and TDD catch this?


Often. At my last employer, we ran into it all the time with Prototype-dependent libraries. It was very common for us to rely on a single-developer open-source project or ISV for a component, find that they depended upon Prototype, then find that they depended upon different versions of Prototype and adding one component would mysteriously make the other fail.

You can't unit-test every combination of libraries that your potential users may eventually install. And if you are a user, you have no feedback on which library caused the failure other than testing every combination of installed libraries, which can be literally hundreds of possibilities.

For my recent projects, I just refuse to use libraries that modify built-in prototypes or dump lots of functions in the global namespace. I use JQuery and I'm willing to use YUI (though I haven't had a need for it...), because they play nicely together. I'll use anything else with similar care put into namespacing. But if it's not namespace-aware, I'll reimplement it rather than take the risk of it breaking other libraries down the road.


Testing for problems is one way to not get burned by bad code, but the best way to avoid being burned is to not write bad code in the first place.

Hint: it's bad to globally modify classes. You should keep your modifications scoped to the smallest part of your program possible. (This is also why we stopped using global variables.)


This is can be a pain if you are using the prototype library and trying to mix it with another library.


Smalltalk programmers extend built-in classes all the time. Learning that changed my perspective on this question.


Check out the dateJS[0] library if you want to do more with dates.

[0] http://www.datejs.com/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: