The problem is the global scope. In other words, every change you make affects the whole code base, and yours may in turn be affected in any location of the code base.
Imagine that you want to loop through all elements of an array; imagine that browsers don't support it yet. For that, you create a method forEach
which is called this way:
[5, 7, 1, 1, 3].forEach(function (element) {
// Do something here.
});
You implemented this method, thought about some edge cases (what about an empty array, for example?) and everything is fine, except a slight performance bug you missed: in some cases, the enumeration is very slow.
Now, somewhere else, your colleague had this great idea of having a forEach
method, but doesn't know you have already implemented one; actually, he even tried to call forEach
on an array to ensure the method doesn't exist yet, but since your code is not executed on every page, [].forEach
returns undefined
.
So he creates his own implementation, but forgets to test it for an empty array, and, in fact, when the array is empty, his code fails.
Back to your code, one day you find a bug report telling that there is a error around forEach
: when the array is empty, it fails. You don't know that your colleague had his own implementation of forEach
which overwrites yours on some pages. Therefore, you think that it's your code which is concerned, so you spend hours wondering why is it failing, while your unit tests pass.
You end up finding the culprit, that is the duplicated forEach
, and you decide to remove the code of your colleague—yours is better. The next day, a new bug report tells that [].forEach
returns undefined
on some pages—that is pages where your code is not executed. WTF!
Together with your colleague, you spend additional two hours resolving this issue. Finally, you are now sure that your code is executed on every page, and you have a clean code where the prototype is added only if there is no forEach
method already:
if (![].forEach) {
Array.prototype.forEach = function (...) {
...
};
}
Meanwhile, the small performance bug you had in your code is discovered, but it appears that it is more a feature, and several of your colleagues are relying on this bug: in several locations, they absolutely need the enumeration to be slow in order to have enough time to show a few images. Since rewriting their code seems to be a nightmare, you decide to keep the bug.
A year later, one morning, you discover dozens of bug reports from dozens of customers. Something is going on. Somebody on your team discovers that all bug reports are from users of Chrome, and further analysis finds that the JavaScript engine of the newly released version of Chrome has forEach
, with the difference that it doesn't have your bug/feature your colleagues were relying on. Now, your team will spend two days adapting the code to the new, bug-less implementation of forEach
.