性能也是一个原因。有时您可能需要遍历键。做这件事有很多种方法
for (let key in object) { ... }
for (let key in object) { if (object.hasOwnProperty(key) { ... } }
for (let key of Object.keys(object)) { ... }
我通常使用for of Object.keys()
它做正确的事,并且相对简洁,无需添加支票。
但是,它要慢得多。
只是猜测Object.keys
慢的原因是显而易见的,Object.keys()
必须进行分配。实际上AFAIK从那以后必须分配所有密钥的副本。
const before = Object.keys(object);
object.newProp = true;
const after = Object.keys(object);
before.join('') !== after.join('')
JS引擎可能会使用某种不可变键结构,以便Object.keys(object)
返回对迭代不可变键进行迭代的引用,并object.newProp
创建一个全新的不可变键对象,但是无论如何,它的速度显然要慢15倍
即使检查hasOwnProperty
速度也要慢2倍。
所有这些的要点是,如果您具有对性能敏感的代码并且需要遍历键,那么您希望能够使用for in
而不必调用hasOwnProperty
。如果您尚未修改,则只能这样做Object.prototype
请注意,如果您使用Object.defineProperty
添加的东西无法枚举来修改原型,那么在上述情况下它们不会影响JavaScript的行为。不幸的是,至少在Chrome 83中,它们确实会影响性能。
我添加了3000个非枚举属性,以试图强制出现任何性能问题。仅使用30个属性,测试太接近以至于无法确定是否有任何性能影响。
https://jsperf.com/does-adding-non-enumerable-properties-affect-perf
Firefox 77和Safari 13.1在增强和未增强类之间的性能没有差异,也许v8在该区域得到修复,您可以忽略性能问题。
但是,让我也添加一个故事Array.prototype.smoosh
。简短的版本是Mootools,这是一个受欢迎的库,它们是自己制作的Array.prototype.flatten
。当标准委员会试图添加本地人时,Array.prototype.flatten
他们发现不能破坏很多站点是不可能的。发现中断的开发人员建议将es5方法命名smoosh
为一个玩笑,但人们吓坏了,不明白这是个玩笑。他们定居flat
而不是flatten
这个故事的寓意是您不应该扩展本机对象。如果这样做,您可能会遇到同样的东西中断问题,除非您的特定库恰好与MooTools一样流行,否则浏览器供应商不太可能解决您引起的问题。如果您的图书馆确实受到欢迎,那将是迫使其他所有人解决您引起的问题的一种方式。所以,请不要扩展本机对象