开发者

Extending Object.prototype JavaScript

I am not asking if this is okay:

Object.prototype.metho开发者_开发技巧d = 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?


UPDATE from 2021

Despite this being the accepted answer, 10 years of experience has taught me this isn't the best idea. Pretty much anything you can do to avoid polluting the global scope is a very very good thing.

Original answer below, for posterity, and because stack overflow will not let me delete an accepted answer.


Original answer from 2011

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.


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;
    }
}


.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.


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.

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜