パフォーマンスも理由です。キーをループする必要がある場合があります。これを行うにはいくつかの方法があります
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()
が、割り当てを行う必要があります。実際、私の知る限り、それ以降、すべてのキーのコピーを割り当てる必要があります。
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倍遅くなります。
これらすべての要点は、perfセンシティブなコードがあり、キーをループする必要がある場合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と同じくらい人気がなければ、ブラウザベンダーが原因で問題を回避することはできません。ライブラリがその人気を博した場合、あなたが引き起こした問題を他のすべての人に回避させることは一種の意味になるでしょう。したがって、ネイティブオブジェクトを拡張しないでください。