2

我一直在浏览 Mozilla Developer Network (MDN) 上的 polyfill 实现,因为我需要其中一些作为库。我知道 shim.js 存在,但我没有使用它。

似乎 polyfill 在代码样式上并不一致。看起来它们几乎是由社区以几乎“维基”的风格编写的。

举个例子String.prototype.contains

if(!('contains' in String.prototype)) {
    String.prototype.contains = function(str, startIndex) {
        return -1 !== String.prototype.indexOf.call(this, str, startIndex);
    }
}

对我来说,这样实现它似乎更合乎逻辑:

if(!String.prototype.contains) {
    String.prototype.contains = function(str, startIndex) {
        return this.indexOf(str, startIndex) !== -1;
    }
}

鉴于 JavaScript 是一种对大小至关重要的语言(因为对于网络传输,一切都应该尽可能小),我的示例应该对 MDN 上的示例有利,因为这可以节省一些字节。

正如标题所暗示的,我想知道代码在 MDN 上的可靠性如何,我是否应该根据需要对其进行修改以尽可能提供真正干净、微小的实现?

4

1 回答 1

9

看来您的问题是指有关 String.contains() 的文章

是的,MDN 是一个 wiki,因此其内容(包括代码示例)的质量可能会有所不同。但是,一般 Web 主题的内容(例如与扩展开发相反)通常非常好。不过,你不应该忘记使用常识。

MDN 上建议的 polyfill 和您的版本在三点上有所不同:

  • !('contains' in String.prototype)!String.prototype.contains检查属性是否存在:前者显然更可取。操作员只是查找一个属性,in没有副作用。!String.prototype.contains另一方面,实际上将检索该属性的值并将其转换为布尔值。这不仅会稍微慢一些,而且某些属性值(例如)0会被错误地强制转换为false. 您可能不会注意到函数的区别,但这可能会在填充其他属性类型时成为一个真正的问题。
  • -1 !== foofoo !== -1比较:这是一个口味问题,但有些人更喜欢前一种变体。在比较中始终将常量放在首位的好处是,您不会无意中将比较变成赋值:按-1 = foo您的意思写-1 == foo会导致错误。另一方面,foo = -1而不是foo == -1会成功并注意到代码中的问题可能需要一段时间。显然,如果您选择适应这种风格,您需要在所有代码中始终如一地使用它。
  • String.prototype.indexOf.callvs. this.indexOf:前者防止对象indexOf上的方法this被覆盖的情况。因此,它更接近原生String.contains()函数的行为。考虑这个例子:
var a = "foo";
a.indexOf = function() {something_weird};
alert(a.contains("f"));

即使被覆盖, polyfill的本机实现String.contains和使用也将起作用 - 但是使用 polyfill将失败。String.prototype.indexOf.callthis.indexOfthis.indexOf

总而言之,MDN 上提供的代码还有一些故障保险。当然,没有给出在您的个人场景中是否需要这些。然而,为了节省几个字节而放弃它们是错误的优化方法(“过早的优化是万恶之源”)。就个人而言,我更喜欢良好的风格而不是效率,除非已知性能差异是相关的。

于 2013-06-20T11:48:57.440 回答