简体   繁体   中英

Extending Object.prototype JavaScript

I am not asking if this is okay:

Object.prototype.method = function(){};

This is deemed evil by pretty much everyone, considering it messes up for(var i in obj) .

The Real Question

Ignoring

  • Incompetent browsers(browsers that don't support Object.defineProperty )
  • Potential for property collision or overriding

Assuming you have some incredibly useful method, is this considered wrong/unethical?

Object.defineProperty(Object.prototype, 'methodOnSteriods',{
  value: function(){ /* Makes breakfast, solves world peace, takes out trash */ },
  writable: true,
  configurable: true,
  enumerable: false
});

If you believe the above is unethical, why would they even implement the feature in the first place?

I think it's fine if it works in your target environment.

Also I think prototype extension paranoia is overblown. As long as you use hasOwnProperty() like a good developer that it's all fine. Worst case, you overload that property elsewhere and lose the method. But that's your own fault if you do that.

I'd say this is almost as evil as before. The biggest problem, still the same as before, is that Object.prototype is global . While your method might currently be solving world peace, it might have overwriten someone else's method (that was guaranteeing galactic peace) or may be overwritten in the future by some library you have no control over (therefore plunging the world into chaos again)


New versions of Javascript have lots of features related to properties, such as definig a property to be enumerable/not enumerable, having getters and setters... Object.defineProperty existis to give control over this.

From Mozilla Docs :

This method allows precise addition to or modification of a property on an object. Normal property addition through assignment creates properties which show up during property enumeration (for...in loop), whose values may be changed, and which may be deleted. This method allows these extra details to be changed from their defaults.


This new function is basically required to support the new features and you are supposed to use it on your own stuff. Being able to modify Object.prototype is just a side effect of it also being a "normal" object and is just as evil as before.

.hasOwnProperty() will exclude iteration through inherited properties, which I personally find is often more annoying than helpful. It largely defeats the usefulness of Object.create() —which is ironic since the same guy who convinced everyone to do .hasOwnProperty() also promoted Object.create() .

Object.prototype should not be extended, for the reasons listed here. If you really do want to extend it, then make the extensions non-iterable.

I realize this flies in the face of all of the published best-practices, but we really should stop “mandating” .hasOwnProperty() on object key iterations and embrace the usefulness of direct object-to-object inheritance.

Well in "JavaScript: the good parts", there is a similar function, i think that is very usefull to improve javascript base objects (like String, Date, etc..), but just for that.

// Add a method conditionally. from "JavaScript: the good parts"

Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
    }
}

The short answer is Yes, you should do it.

Before doing it, there are several precautions need to take:
1. using hasOwnProperty when iterating object, but this isn't really a precautions, when iterating object, I am already using hasOwnProperty anyway.
2. check if the name in Object.prototype.name has existed, this is very safe to avoid name collision.
3. take advantage of Object.defineProperty() , just add extra safeguard layer.

As you can see, it's not very complicated.

Now comes the advantages once you have taken care of the risks/disadvantages:
1. method chaining, this just makes code more readable, terse, and making coding more enjoyable. In turn makes you happier, and your life easier.
2. solves the browser compatibility issue, you are doing polyfill anyway.

PS:
Don't do it when working with a large team for sure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM