JS __proto__ «забавный» факт

Если вы следили за мной достаточно долго, вы уже знаете, насколько __proto__
я всегда был против, и все же, поскольку он уже давно стал стандартом ECMAScript , все еще есть редкие случаи, когда я нахожу, по крайней мере, его использование для маркировки объекта приемлемым :
const factory = (fields, {prototype} = Object) => ({
__proto__: prototype,
...fields
});
// mimic an <a /> reference
factory({href: '/'}, HTMLAnchorElement);

Отложив производительность в сторону, и обратите внимание, что я вообще не предлагаю использовать __proto__
в дикой природе, этот пост существует по другим причинам.
Объект.прототип.__прото__
Я почти уверен, что все знают, что делает аксессор __proto__ , поэтому я хотел бы предложить вам вызов… и да, это все допустимый JS:
class Test {}
const __proto__ = Test.prototype;
// what do these operations return?
({__proto__} instanceof Test);
({__proto__: __proto__} instanceof Test);
({"__proto__": __proto__} instanceof Test);
({["__proto__"]: __proto__} instanceof Test);
// what do these operations return?
({__proto__}.__proto__ === Test.prototype);
({__proto__: __proto__}.__proto__ === Test.prototype);
({"__proto__": __proto__}.__proto__ === Test.prototype);
({["__proto__"]: __proto__}.__proto__ === Test.prototype);
Если вы еще не запустили эти фрагменты, чтобы узнать ответ, я могу помочь с этим! В первом вызове на выходе будет false
, true
, true
и false
снова, и причина в том, что и то, {__proto__}
и другое {["__proto__"]}
определяется как собственное свойство , а присваивание через синтаксис, без использования специальных синтаксических возможностей, даже с кавычками, проходит фактически через Object.prototype.__proto__
аксессор.
С другой стороны, во втором вызове (all true
) на самом деле не имеет значения, обращаемся ли мы __proto__
напрямую или как ["__proto__"]
, так что в основном существует нулевая симметрия в том, как мы можем запускать __proto__
сеттер, по сравнению с тем, как мы можем запускать __proto__
геттер один раз . это либо собственная собственность, либо волшебные ворота наследства.
… и не только __proto__
Я не проверял себя, но я считаю, что каждый устаревший __xxx__
специальный метод доступа страдает от одного и того же __proto__
проклятия, поэтому, пожалуйста, будьте осторожны, смешивая новейший классный синтаксис JS для назначения свойств с вашими фактическими намерениями и ожиданиями, так как все может легко пойти не так, если вы попытаетесь будьте умны в назначении этих свойств .
И это все люди!
Единственный вывод из этого поста, вероятно, можно резюмировать так:
- не используйте устаревшие, но работающие части языка, если вы хотите избежать сюрпризов сегодня или завтра в отношении того, как они ведут себя с новым синтаксисом
- предпочитать явный (и, к сожалению, более медленный)
Object.setPrototypeOf
всякий раз, когда строго требуется ручная установка прототипа объекта, но использовать классы во всех остальных случаях, когда это возможно - сотрите из своей памяти этот пост или сократите его до короткого предложения, например: « Я никогда не должен использовать
__proto__
в своем коде », и продолжайте изучать новые причудливые вещи, которые не испортят ваш мозг или чувства .