blockquote>// This is bad: //foo.__proto__.bar = bar; // But this is okay Foo.prototype.bar = bar;
Нет. Оба делают то же самое (как
foo.__proto__ === Foo.prototype
), и оба прекрасны. Они только создают свойствоbar
на объектеObject.getPrototypeOf(foo)
.То, о чем говорится в заявлении, это присвоение самому свойству
__proto__
:function Employee() {} var fred = new Employee(); // Assign a new object to __proto__ fred.__proto__ = Object.prototype; // Or equally: Object.setPrototypeOf(fred, Object.prototype);
предупреждение на странице
Object.prototype
более подробно:Мутирование [[Prototype]] объекта по характеру, как оптимизируются современные JavaScript-движки доступ к ресурсам, очень медленная операция
blockquote>Они просто заявляют, что изменяет цепочку прототипов уже существующего объекта убивает оптимизацию . Вместо этого вы должны создать новый объект с другой цепочкой прототипов через
Object.create()
.Я не мог найти явную ссылку, но если мы рассмотрим, как скрытые классы V8 , мы можем видеть, что здесь может произойти. При изменении последовательности прототипов объекта изменяется его внутренний тип - он не просто становится подклассом, как при добавлении свойства, но полностью заменяется. Это означает, что все исправления поиска свойств очищаются, и предварительно скомпилированный код нужно будет отбросить. Или он просто возвращается к неоптимизированному коду.
Некоторые заметные цитаты:
- Брендан Эйх (вы его знаете) сказал Writable __proto__ is гигантская боль для реализации (должна быть сериализована для проверки цикла) и создает всевозможные угрозы путаницы.
- Брайан Хакетт (Mozilla) сказал : разрешая скриптам мутировать прототип практически любого объекта, затрудняет рассуждение о поведении скрипта и делает VM, JIT и реализация анализа более сложная и более сложная. Вывод типа имеет несколько ошибок из-за изменчивого __proto__ и не может поддерживать несколько желательных инвариантов из-за этой функции (т.е. «наборы типов содержат все возможные типы объектов, которые могут реализоваться для var / property» и «JSFunctions имеют типы, которые также являются функциями», ).
- Джефф Уолден сказал : мутация прототипа после создания с его неустойчивой дестабилизацией производительности и воздействием на прокси и [[SetInheritance]]
- Эрик Корри (Google) сказал, что : я не ожидаю, что большой прирост производительности приведет к тому, что proto не будет перезаписываться. В неоптимизированном коде вам нужно проверить цепочку прототипов, если объекты прототипа (а не их личность) были изменены. В случае оптимизированного кода вы можете вернуться к неоптимизированному коду, если кто-то пишет в proto. Таким образом, это не принесло бы такой большой разницы, по крайней мере, в V8-Crankshaft.
- Эрик Фауст (Mozilla) сказал . Когда вы устанавливаете __proto__, вы не только разрушаете любые шансы, которые вы, возможно, имели для будущих оптимизаций от Ion на этом объекте, но также заставляете движок, чтобы обходить все остальные части вывода типа (информация о значениях возвращаемых функций или значений свойств, возможно), которые, по их мнению, знают об этом объекте и говорят им не делать много предположений, что предполагает дальнейшую деоптимизацию и, возможно, аннулирование существующего jitcode. Изменение прототипа объекта в середине исполнения на самом деле является неприятным кувалдой, и единственный способ, которым мы должны избегать неправильного, - это безопасно играть, но безопасный медленный.