1

I was reading the readme for should.js and got to the "OMG IT EXTENDS OBJECT???!?!@" section which says

Yes, yes it does, with a single getter should, and no it won't break your code, because it does this properly with a non-enumerable property.

I've always heard you shouldn't extend the object prototype but never really understood why.

Can someone explain why, in general, extending object is bad (what can it break)? And also explain what a non-enumerable property is and how this helps?

Brad Dwyer
  • 6,305
  • 8
  • 48
  • 68
  • See http://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice and http://stackoverflow.com/questions/6877005/extending-object-prototype-javascript for some discussion on this. – Crescent Fresh Jun 08 '13 at 19:17

1 Answers1

1

The issue is with extending Object.prototype. If the extension is enumerable, then it will be encountered in every enumeration of every object when using for-in.

Object.prototype.foo = "bar";

var empty_object = {};

for (var p in empty_object) {
    alert(p + " " + empty_object[p]);
}

Clearly this can mess with your code. You can use .hasOwnProperty() in every enumeration of every object property, but there's a performance impact. Also sometimes you actually want to include inherited properties in your enumeration, but this makes it impossible, or at least very tough.


You should also note that just because the property is marked non-enumerable, that doesn't mean that it won't break your code.

What if you have an object, and you need to get the value of the .should property if it exists? (Where .should is expected to have some other meaning in the code.)

var val = my_object.should;

if (val) {
    // do something
} else {
    // do something else
}

Trouble is that the .should property will now always return the value of the inherited property if there isn't one directly on my_object.

This issue exists for the native Object.prototype extensions, but at least those names are commonly known, and therefore habitually avoided.


It's good that the library documented this extension, but it's still pretty short-sighted to claim that it won't break your code.

Least they could do would be to make it an optional extension.