JS __proto__ „zabawny” fakt

Jeśli śledzisz mnie wystarczająco długo, już wiesz, jak bardzo __proto__
zawsze byłem przeciwny, a jednak, odkąd dawno temu dotarł do standardu ECMAScript , wciąż zdarzają się rzadkie sytuacje, w których uważam, że przynajmniej jego użycie do oznakowania obiektu jest akceptowalne :
const factory = (fields, {prototype} = Object) => ({
__proto__: prototype,
...fields
});
// mimic an <a /> reference
factory({href: '/'}, HTMLAnchorElement);

Odkładając wydajność na bok i pamiętaj, że nie sugeruję używania __proto__
w ogóle na wolności, ten post istnieje z innych powodów.
Obiekt.prototyp.__proto__
Jestem prawie pewien, że każdy wie, co robi akcesor __proto__ , więc chciałbym zaproponować ci wyzwanie… i tak, to wszystko jest poprawnym 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);
Jeśli nie uruchomiłeś tych fragmentów, aby poznać odpowiedź, mogę w tym pomóc! W pierwszym wyzwaniu wynikiem będzie false
, true
, true
i false
znowu, a powodem jest to, że oba {__proto__}
i {["__proto__"]}
są zdefiniowane jako własna właściwość , podczas gdy przypisanie za pomocą składni, bez użycia specjalnych funkcji składni, nawet z cudzysłowami, przechodzi faktycznie przez Object.prototype.__proto__
akcesor.
Z drugiej strony, w drugim wyzwaniu (all true
) tak naprawdę nie ma znaczenia, czy uzyskujemy dostęp __proto__
bezpośrednio, czy jako ["__proto__"]
, więc w zasadzie nie ma symetrii w sposobie, w jaki możemy uruchomić __proto__
setera, od sposobu, w jaki możemy uruchomić __proto__
gettera raz albo jest to własność własna, albo magiczna brama spadkowa.
…i nie tylko __proto__
Nie sprawdzałem tego osobiście, ale uważam, że każdy starszy __xxx__
specjalny akcesor cierpi na tę samą __proto__
klątwę, więc bądź ostrożny, mieszając najnowszą fajną składnię JS, aby przypisać właściwości z twoimi faktycznymi intencjami i oczekiwaniami, ponieważ wszystko może łatwo pójść na marne, jeśli spróbujesz bądź sprytny w przypisywaniu tych właściwości .
I to wszystko ludzie!
Jedyny wniosek z tego postu jest prawdopodobnie podsumowany w następujący sposób:
- nie używaj starszych, ale działających części języka, jeśli chcesz uniknąć niespodzianek dzisiaj lub jutro, jak zachowują się one z nową składnią
- preferuj jawne (i niestety wolniejsze)
Object.setPrototypeOf
zawsze, gdy ręczne ustawienie prototypu obiektu jest bezwzględnie wymagane, ale używaj klas w każdym innym przypadku, kiedy tylko jest to możliwe - wymaż ten post z pamięci lub skróć go do krótkiego zdania, takiego jak: „ Nigdy nie powinienem używać
__proto__
w moim kodzie ” i idź dalej, ucząc się wymyślnych nowych rzeczy, które nie zaśmiecają twojego mózgu ani uczuć