モダンjavascript-Deep Dive 16[プロツリー]


けいかく


内部スロットと内部メソッド


内部スロットおよび内部メソッドは、jsエンジンの実装アルゴリズムを記述するためにECMAScript仕様で使用される擬似プログラムおよび擬似メソッドである.どちらもECMAScript仕様で定義された実装に従い、jsエンジンで実際に実行されますが、開発者は直接アクセスできません.
ただし,一部の内部スロットと内部メソッドに限られ,間接アクセスの手段が提供される.
const o = {};
// 내부 슬롯은 js 엔진의 내부 로직이므로 접근이 불가하다.
o.[[Prototype]]; // Error

//단, 일부 내부 슬롯과 내부 메서드에 한하여 간접적으로 접근할 수 있는 수단을 제공한다
o.__proto__; // Object.prototype

PropertyツリーとPropertyディスク立棒オブジェクト


jsエンジンはpropertyの作成時にpropertyステータスを表示するpropertyツリーを自動的にデフォルト値として定義します
特典ステータス
value(値)、writable(値更新可能)、enumerable(リスト可能)、configurable(再定義可能)
Property Trevityには直接アクセスできませんが、オブジェクトです.getownPropertyDescriptorメソッドを使用して間接的に確認できます
const ps = { name : "Lee"};

Object.getOwnPropertyDescriptor(ps,"name"); // 첫 파라미터 에 객체의 참조를 전달하고, 두번째 매개변수에 프로퍼티 키
// 	{value: 'Lee', writable: true, enumerable: true, configurable: true}
//  반환된 프로퍼티 디스크럽터 객체이다.

データ・リソースとビジター・リソース


データプロバイダ


キーと値からなる一般的なプログラム.

訪問者の割合


あるアクセス者関数からなるプログラムは、別のデータ・プロシージャの値を読み出したり格納したりするときに、それ自体に値を持たない.

アクセス者関数はgetter/setter関数とも呼ばれます.
const person = {
  firstName: "Ungmo",
  lastName: "Lee",

  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  },

  set fullName(name) {
    [this.firstName, this.lastName] = name.split(" ");
  },
};
console.log(person.firstName + " " + person.lastName); // Ungmo Lee
//  set fullName(name)
person.fullName = "Heegun Lee";
console.log(person); // { firstName: 'Heegun', lastName: 'Lee', fullName: [Getter/Setter] }
//  get fullName()
console.log(person.fullName); // Heegun Lee

let descriptor = Object.getOwnPropertyDescriptor(person, "fullName");
console.log(descriptor);
// 접근자 프로퍼티
// {get: [Function: get fullName],set: [Function: set fullName],enumerable: true,configurable: true}
get内部メソッド動作プロセス
1.propertyキーの有効/propertyキーが文字列または記号であることを確認します.
2.prototypeチェーンでpropertyを検索する
3.このプロトコルがデータ・プロトコルかビジター・プロトコルかを確認する
4.該当するアクセス者PropertyFullNameのPropertyツリー[Get]に戻ります.
ここでプロトタイプとは何ですか?
オブジェクトの親オブジェクトを逆方向に操作するオブジェクト.プロトタイプは、自分のプロトタイプとメソッドをサブオブジェクトに継承します.

構成定義


Property定義は、新しいPropertyを追加するときにPropertyツリーを明確に定義するか、既存のPropertyのPropertyツリーを再定義することを意味します.
const person = {};

Object.defineProperty(person, "firstName", {
  value: "Ungmo",
  writable: true,
  enumerable: true,
  configurable: true,
});

Object.defineProperty(person, "lastName", {
  value: "Lee",
  // 디스크럽터 객체의 프로퍼티를 누락 시키면 undefined, false가 기본값이다.
});

console.log(Object.getOwnPropertyDescriptors(person));

console.log(Object.keys(person));
//  [ 'firstName' ] 
//  enumerable 열거 옵션 false   

person.lastName = "Kim"
//  에러는 안나지만 바뀌지 않는다. writable 값 변경 가능 옵션 false

delete person.lastName;
//  에러는 안나지만 삭제되지 않는다. configurable 프로퍼티 재정의 가능 옵션 false
ディスクフラクチャオブジェクトのデフォルトの設定

オブジェクトの変更を防止


jsは、オブジェクトの変更を防止するためのさまざまな方法を提供します.

Object.preventExtensionsメソッドは拡張を禁止し、propertyの追加を禁止します.
Object.Seal法は密封されており,すなわち読み取りと書き込みのみが許可されている.
Object.フリーズメソッドの場合、フリーズは読み取り専用です.

不変オブジェクト


Object.freezeメソッドではネストされたオブジェクトにフリーズできません
オブジェクトのネストされたオブジェクトをフリーズするには、オブジェクトを値のすべてのプロパティとして再帰することができます.freezeメソッドを呼び出す必要があります.
function deepFreeze(target) {
  if (target && typeof target === "object" && !Object.isFrozen(target)) {
    Object.freeze(target);

    Object.keys(target).forEach((key) => deepFreeze(target[key]));
  }
  return target;
}