代码之家  ›  专栏  ›  技术社区  ›  JasonWyatt

修改javascript的内置原型是一种反模式吗?

  •  1
  • JasonWyatt  · 技术社区  · 15 年前

    我是从 this post ,这是一个需要修改的反模式 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);
    };

    我没有测试过这个代码,但你知道。这样做是否违背了“最佳实践”?

    6 回复  |  直到 15 年前
        1
  •  3
  •   James Black    15 年前

    一般来说,如果您要向JavaScript中的一个基本对象添加原型,那么您应该有一个很好的理由,而且实际上没有理由修改对象,因为您不知道如何预测修改的最终结果。

    我倾向于在字符串中添加startswith、trim和其他一些函数,例如,这些函数是帮助函数,就像在firefox中存在的数组中添加一些函数一样,而不是ie只是有意义的函数(例如filter函数)。

    所以,添加到画布上是很好的,但是,如果有人正在使用您的库,并使用excanvas呢?会引起问题吗?

    您可能想探索这个问题,或者记录它对Excanvas不起作用,如果您有一个小测试来证明这一点,请将其包括在内,这样如果以后有一个新版本,并且您的问题消失了,人们可以验证这一点。

    更新: 您将要执行此操作:

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

    这样,如果有人用这个名字包含了一个,你就不会覆盖它,但你需要优雅地处理它。

        2
  •  4
  •   Frank Schwieterman    15 年前

    我不会这样做,因为这样很难跟踪在哪里实现了什么。它还引入了两个人凌驾于同一行为之上的风险。

        3
  •  1
  •   zac    15 年前

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

        4
  •  1
  •   Josh Stodola    15 年前

    所有这些“反模式”的建议都不能被盲目采纳。不管他们怎么说,有时候最好的答案就是咬紧牙关,违反惯例,让事情正常运转。当然,这在很大程度上取决于您的场景。

    我想起了这样一种情况,在这种情况下,花了几天时间重新组织代码,以“正确的方式”进行适当的修复,当一个简单的转到将起到很好的作用,并且只需要几分钟就可以实现。最后,由于代码被更改而不需要更改,所以创建了一系列错误。我是Go-to声明的粉丝吗?见鬼!但是,如果使用一个可以防止数月的头痛,那就没有问题了。

        5
  •  0
  •   Daniel A. White    15 年前

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

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

    有趣的是,C现在有了所谓的扩展方法,它可以有效地执行相同的操作。

        6
  •  0
  •   Kimmo Puputti    15 年前

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