JS __proto__ "재미있는" 사실

Nov 26 2022
오랫동안 저를 따라오셨다면 제가 항상 __proto__에 대해 얼마나 반대했는지 이미 알고 계실 것입니다. 그러나 오래 전에 ECMAScript 표준에 도달했기 때문에 객체를 브랜딩하는 데 적어도 사용되는 경우는 여전히 드뭅니다. 허용 가능: 성능을 제쳐두고, 야생에서 __proto__의 사용을 전혀 제안하지 않는다는 점에 유의하십시오. 이 게시물은 다른 이유로 존재합니다. 물체.
Unsplash의 Mark Williams 사진

__proto__오랫동안 저를 따라오셨다면 제가 항상 얼마나 반대했는지 이미 알고 계실 것 입니다. 하지만 오래 전에 ECMAScript 표준을 만들었기 때문에 적어도 객체를 브랜드화하는 데 사용되는 경우는 드물다고 생각합니다. :

const factory = (fields, {prototype} = Object) => ({
  __proto__: prototype,
  ...fields
});

// mimic an <a /> reference
factory({href: '/'}, HTMLAnchorElement);

Firefox에서 __proto__는 new Class보다 더 나은 점수를 얻습니다.

성능은 제쳐두고 __proto__야생에서 사용을 전혀 제안하지 않는다는 점에 유의하십시오. 이 게시물은 다른 이유로 존재합니다.

객체.프로토타입.__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__}and {["__proto__"]}자체 속성으로 정의되는 반면 구문을 통한 할당은 특별한 구문 기능을 사용하지 않고 인용 부호가 붙어 있어도 실제로 접근자를 통과하기 때문 Object.prototype.__proto__입니다.

반면에 두 번째 챌린지(all )에서는 직접 액세스하거나 as 로 true액세스하는 것이 중요하지 않으므로 기본적으로 getter를 한 번 트리거할 수 있는 방식에서 setter를 트리거할 수 있는 방식에 제로 대칭이 있습니다. 그것은 자신의 재산이거나 마법의 상속 게이트입니다.__proto__["__proto__"]__proto____proto__

… 그리고 __proto__ 뿐만 아니라

직접 확인하지는 않았지만 모든 레거시 __xxx__특수 접속자가 동일한 저주를 겪고 있다고 생각 __proto__하므로 최신 멋진 JS 구문을 혼합하여 실제 의도 및 기대에 따라 속성을 할당하는 데 주의하십시오. 이러한 속성 을 현명하게 할당 하십시오.

그리고 그게 전부입니다!

이 게시물의 유일한 내용은 다음과 같이 요약될 수 있습니다.

  • 오늘 또는 내일 새로운 구문으로 작동하는 방식에 대해 놀라움을 피하려면 언어의 레거시 아직 작동하는 부분을 사용하지 마십시오.
  • Object.setPrototypeOf객체의 프로토타입을 수동으로 설정해야 할 때마다 명시적(불행하게도 더 느린)을 선호 하지만 가능하면 다른 모든 경우에 클래스를 사용하십시오.
  • 이 게시물을 기억 __proto__에서 지우거나 다음과 같은 짧은 문장으로 축소 하세요 .