Perf - тоже причина. Иногда вам может потребоваться перебрать ключи. Есть несколько способов сделать это
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 не показали разницы в производительности между классами Augmented и Unaugmented, возможно, v8 будет исправлен в этой области, и вы можете игнорировать проблемы производительности.
Но позвольте мне также добавить, что есть историяArray.prototype.smoosh
. Краткая версия - это популярная библиотека Mootools, созданная самостоятельно Array.prototype.flatten
. Когда комитет по стандартам попытался добавить родной язык, Array.prototype.flatten
они обнаружили, что не могут не сломать множество сайтов. Разработчики, которые узнали о перерыве, предложили назвать метод es5 smoosh
шуткой, но люди испугались, не поняв, что это шутка. Они остановились flat
вместоflatten
Мораль этой истории в том, что вы не должны расширять родные объекты. Если вы это сделаете, вы можете столкнуться с той же проблемой, что и ваши вещи, и если ваша конкретная библиотека не станет такой же популярной, как MooTools, поставщики браузеров вряд ли решат проблему, которую вы вызвали. Если ваша библиотека действительно станет такой популярной, это будет означать, что все остальные будут работать над проблемой, которую вы вызвали. Итак, пожалуйста, не расширяйте собственные объекты