我从this post了解到,在JavaScript中修改Object
原型是一种反模式。然而,我很好奇,如果它被广泛认为是修改其他“内置”原型的反模式。
例如:假设我们要向setPixel(x,y,color)
添加CanvasRenderingContext2D
函数 - 以抽象出获取上下文图像数据的义务,将像素设置为某种颜色,以及放置图像数据回来。
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);
};
我没有测试过这段代码,但是你明白了。对“最佳实践”这样的事情是这样的吗?
答案 0 :(得分:4)
我不会这样做,因为它很难跟踪在哪里实施。它还引入了两个人压倒相同行为的风险。
答案 1 :(得分:3)
通常,如果要将一个原型添加到JavaScript中的一个基础对象中,您应该有充分的理由,并且没有理由修改Object,因为您不知道如何预测最终结果将是那种修改。
我倾向于将startsWith,trim和其他一些函数添加到String中,例如,因为这些是辅助函数,就像为Firefox存在的一些函数添加一些函数而不是IE才有意义(例如过滤函数)
所以,添加到Canvas很好,但是,如果有人使用你的库,并使用excanvas会怎样。它会引起问题吗?
您可能想要探索它,或者说它不适用于excanvas,如果您有一个小测试来显示它,请包含它,以便以后有新版本和您的问题消失的人可以验证。
<强>更新强> 你会想要这样做:
if (!CanvasRenderingContext2D.setPixel) {
...
}
这样,如果有人确实包含了一个名称,你就不会覆盖它,但你需要优雅地处理它。
答案 2 :(得分:1)
绝对不是;如果方法以这种方式与对象相关,那么这是一个优雅的解决方案。
答案 3 :(得分:1)
所有这些“反模式”建议都不应盲目采纳。无论他们说什么,有时最好的答案是咬紧牙关,违背惯例让事情发生。当然,这在很大程度上取决于您的情况。
我想起了一种情况,即在一个简单的GO TO工作得很好并且只花了几分钟才能实现的情况下,重新组织代码以便以“正确的方式”进行适当的修复。最后,由于代码被更改而不需要更改,因此创建了一堆错误。我是GO TO声明的粉丝吗?一定不行!但如果使用一个可以防止数月的头痛,那么毫无疑问。
答案 4 :(得分:0)
只要功能或命名不会覆盖已存在的内容,我就不会发现任何问题。我知道有些修改了string
函数的Trim
原型。
http://www.somacon.com/p355.php
有趣的是,C#现在拥有所谓的扩展方法,可以有效地做同样的事情。
答案 5 :(得分:0)
并非如此,但如果Ajax库制造商不能依赖内置类型及其属性,则可能会遇到问题。因此,您可以破坏依赖于某些行为的代码。