我一直在浏览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);
}
}
对我来说,实现这一点似乎更合乎逻辑:
if(!String.prototype.contains) {
String.prototype.contains = function(str, startIndex) {
return this.indexOf(str, startIndex) !== -1;
}
}
鉴于JavaScript是一种大小关键的语言(因为网络传输的所有内容应尽可能小),我的示例应该对MDN上的示例有利,因为这会节省几个字节。
正如标题所示,我想知道代码在MDN上的可靠性,我是否应该根据需要对其进行修改以尽可能提供真正干净的微小实现?
答案 0 :(得分:9)
您的问题似乎是the article on String.contains()。
是的,MDN是一个wiki,因此其内容(包括代码示例)的质量可能会有所不同。但是,一般Web主题的内容(例如,与扩展开发相反)通常非常好。不过,你不应该忘记使用常识。
在MDN上建议的polyfill和您的版本有三点不同:
!('contains' in String.prototype)
与!String.prototype.contains
相比,检查属性是否存在:前者显然更为可取。 in
运算符只查找属性,没有副作用。另一方面,!String.prototype.contains
实际上将检索该属性的值并将其转换为布尔值。这不仅会略微变慢,而且0
等某些属性值会被错误地强制转换为false
。您可能不会注意到函数的差异,但在填充其他属性类型时,这可能会成为一个真正的问题。-1 !== foo
与foo !== -1
进行比较:这是一个品味问题,但有些人更喜欢前一种变体。始终将常数置于比较中的优点是,您不会无意中将比较转换为赋值:当您意味着-1 = foo
将导致错误时,编写-1 == foo
。另一方面,foo = -1
代替foo == -1
会成功,并注意到代码中的问题可能需要一段时间。显然,如果您选择调整该样式,则需要在所有代码中始终如一地使用它。String.prototype.indexOf.call
与this.indexOf
:前者防范indexOf
对象this
方法被覆盖的情况。因此,它更接近本机String.contains()
函数的行为。考虑这个例子:var a = "foo";
a.indexOf = function() {something_weird};
alert(a.contains("f"));
String.contains
的原生实施和使用String.prototype.indexOf.call
的填充即使this.indexOf
被覆盖也会有效 - 但使用this.indexOf
的填充会失败。
总而言之,MDN上提供的代码还有一些故障保险。当然不会在您的个人情景中需要这些。然而,丢弃它们以节省几个字节是错误的优化方法(“过早优化是所有邪恶的根源”)。就个人而言,除非已知性能上的差异是相关的,否则我更喜欢良好的风格而非效率。