2

我从这篇文章Object中了解到,在 JavaScript 中修改原型是一种反模式。但是,我很好奇它是否被广泛认为是修改其他“内置”原型的反模式。

例如:假设我们想添加一个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);
};

我没有测试过这段代码,但你明白了。这样的事情是否违反“最佳实践”?

4

6 回答 6

5

我不会这样做,因为它很难跟踪在哪里实施了什么。它还引入了两个人覆盖相同行为的风险。

于 2009-11-04T20:29:12.923 回答
3

一般来说,如果你在 JavaScript 中向其中一个基础对象添加原型,你应该有充分的理由,而且真的没有理由修改 Object,因为你不知道如何预测最终结果会是什么那个修改。

例如,我倾向于向 String 添加startsWith、trim 和其他一些函数,因为这些是辅助函数,就像向 Array 添加一些对 Firefox 存在但不是 IE 的函数才有意义(例如过滤器函数)。

因此,添加到 Canvas 很好,但是,如果有人在使用您的库并使用 excanvas 怎么办。会不会造成问题?

您可能想要探索它,或者记录它不适用于 excanvas,如果您有一个小测试来证明这一点,请包含它,以便如果以后有新版本,并且您的问题消失了人们可以验证这一点。

更新: 你会想要这样做:

if (!CanvasRenderingContext2D.setPixel) {
...
}

这样,如果有人确实包含了该名称的人,您将不会覆盖它,但您需要优雅地处理它。

于 2009-11-04T20:30:57.937 回答
1

当然不; 如果该方法以这种方式与对象相关,那么它是一个优雅的解决方案。

于 2009-11-04T20:29:20.777 回答
1

所有这些“反模式”建议都不能盲目采纳。不管他们说什么,有时最好的答案是咬紧牙关,打破常规,让事情顺利进行。当然,这在很大程度上取决于您的情况。

我想起了这样一种情况,即花费数天时间重新组织代码以“以正确的方式”进行适当的修复,而一个简单的 GO TO 本来可以很好地工作,并且只需要几分钟就可以实现。最后,由于更改了不需要更改的代码,因此产生了一堆错误。我是 GO TO 语句的粉丝吗?一定不行!但是,如果使用一个可以防止几个月的头痛,那么毫无疑问。

于 2009-11-04T20:38:19.700 回答
0

只要功能或命名不覆盖已经存在的内容,我认为没有任何问题。我知道一些会修改函数string原型。Trim

http://www.somacon.com/p355.php

有趣的是,C# 现在有了所谓的扩展方法,它可以有效地做同样的事情。

于 2009-11-04T20:25:04.617 回答
0

不像它本身,但是如果 Ajax 库制造商不能依赖内置类型及其属性,他们可能会遇到问题。因此,您可以破坏依赖于某些行为的代码。

于 2009-11-04T20:35:10.820 回答