问题
I understand from this post, that it's an anti-pattern to modify Object
's prototype in JavaScript. I was curious, however, if it's widely considered to be an antipattern to modify other 'built-in' prototypes.
For example: say we wanted to add a setPixel(x,y,color)
function to CanvasRenderingContext2D
- to abstract out the duty of getting the context's image data, setting a pixel to a certain color, and putting the image data back.
CanvasRenderingContext2D.prototype.setPixel = function(x, y, color){
var imgdata = this.createImageData(1,1);
imgdata.data[0] = color.r;
imgdata.data[1] = color.g;
imgdata.data[2] = color.b;
imgdata.data[3] = color.a;
this.putImageData(imgdata,x,y);
};
I haven't tested this code, but you get the idea. Is something like this against 'best practices' ?
回答1:
Generally, if you are adding a prototype to one of the base objects in JavaScript, you should have a good reason, and there is really no reason to modify Object, since you don't know how to predict what the end result will be of that modification.
I tend to add startsWith, trim and some other functions to String, for example, as these are helper functions, just as adding some functions to Array that exists for Firefox but not IE just makes sense (such as the filter function).
So, adding to the Canvas is fine, but, what if someone is using your library, and using excanvas. Will it cause a problem?
You either may want to explore that, or document that it doesn't work for excanvas, and if you have a small test to show that, please include it, so that if later there is a new version, and your problem disappears people can verify that.
UPDATE: You will want to do this:
if (!CanvasRenderingContext2D.setPixel) {
...
}
That way, if someone did include one by that name you will not overwrite it, but you will need to handle it gracefully.
回答2:
I wouldn't do it as it makes it hard to track what is implemented where. It also introduces the risk of two people overriding the same behavior.
回答3:
Definitely not; if the method is related to the object in this way then it is an elegant solution.
回答4:
All of these "anti-pattern" suggestions are not to be blindly adopted. No matter what they say, sometimes the best answer is to bite the bullet and go against convention to get things working. This, of course, largely depends on your scenario.
I'm reminded of a situation where days were spent re-organizing code to make the appropriate fix "the right way", when a simple GO TO would have worked great and only taken a couple of minutes to implement. In the end, a bunch of bugs were created because code was changed that did not need to be changed. Am I a fan of GO TO statements? Hell no! But if using one prevents a months worth of headaches, then there is no question.
回答5:
I don't see any problem with that as long as the functionality or naming does not override what is already there. I know of some that modify the string
prototype for Trim
functions.
http://www.somacon.com/p355.php
What is funny, C# now has what's called an Extension Method which effectively does the same thing.
回答6:
Not as itself, but the Ajax library makers might have problems if they cannot rely on the builtin types and their properties. So you could break code that relies on certain behaviour.
来源:https://stackoverflow.com/questions/1676383/is-it-an-anti-pattern-to-modify-javascripts-built-in-prototypes