MDN上的polyfill/shim实现的可靠性如何

ser*_*0ne 2 javascript mozilla shim polyfills

我一直在浏览Mozilla开发者网络(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);
    }
}
Run Code Online (Sandbox Code Playgroud)

对我来说,实现这一点似乎更合乎逻辑:

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

鉴于JavaScript是一种大小关键的语言(因为网络传输的所有内容应尽可能小),我的示例应该对MDN上的示例有利,因为这样可以节省几个字节.

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

Wla*_*ant 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"));
Run Code Online (Sandbox Code Playgroud)

即使被覆盖,本机实现String.contains和使用polyfill String.prototype.indexOf.call也会起作用this.indexOf- this.indexOf但是使用polyfill 会失败.

总而言之,MDN上提供的代码还有一些故障保险.当然不会在您的个人情景中需要这些.然而,丢弃它们以节省几个字节是错误的优化方法("过早优化是所有邪恶的根源").就个人而言,除非已知性能上的差异是相关的,否则我更喜欢良好的风格而不是效率.