1. 程式人生 > 其它 >好玩的隱藏屬性

好玩的隱藏屬性

隱藏類

  1. 物件中所包含所有屬性
  2. 每個屬性相對於物件的偏移量
let point = {x:100,y:200}
  1. 在v8中隱藏類又稱為map,每個物件都有一個map屬性,其值指向儲存中的隱藏類

  2. 有了map之後,point.x訪問x屬性時,v8會先查詢point的map中x屬性相對point物件的偏移量,然後將point物件的起始值加上偏移量,就得到x屬性的值在記憶體的位置,有了這個位置也就拿到了x的值

  3. 使用d8看看隱藏類

let point = {x:100,y:200};
%DebugPrint(point);

d8 --allow-natives-syntax test.js 

DebugPrint: 0x4eb080c6019: [JS_OBJECT_TYPE]
 - map: 0x04eb08284ce9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - prototype: 0x04eb08241395 <Object map = 0x4eb082801c1>
 - elements: 0x04eb080406e9 <FixedArray[0]> [HOLEY_ELEMENTS]
 - properties: 0x04eb080406e9 <FixedArray[0]> {
    #x: 100 (const data field 0)
    #y: 200 (const data field 1)
 }
0x4eb08284ce9: [Map]
 - type: JS_OBJECT_TYPE
 - instance size: 20
 - inobject properties: 2
 - elements kind: HOLEY_ELEMENTS
 - unused property fields: 0
 - enum length: invalid
 - stable_map
 - back pointer: 0x04eb08284cc1 <Map(HOLEY_ELEMENTS)>
 - prototype_validity cell: 0x04eb081c0451 <Cell value= 1>
 - instance descriptors (own) #2: 0x04eb080c6049 <DescriptorArray[2]>
 - prototype: 0x04eb08241395 <Object map = 0x4eb082801c1>
 - constructor: 0x04eb082413b1 <JSFunction Object (sfi = 0x4eb081c557d)>
 - dependent code: 0x04eb080401ed <Other heap object (WEAK_FIXED_ARRAY_TYPE)>
 - construction counter: 0

多個物件共用一個隱藏類

  1. 相同的屬性名稱
  2. 相同的屬性個數
let point = {x:100,y:200};
let point2 = {x:3,y:4};
%DebugPrint(point);
%DebugPrint(point2);

d8 --allow-natives-syntax test.js 

DebugPrint: 0x3e0a080c6075: [JS_OBJECT_TYPE]
 - map: 0x3e0a08284ce9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - prototype: 0x3e0a08241395 <Object map = 0x3e0a082801c1>
 - elements: 0x3e0a080406e9 <FixedArray[0]> [HOLEY_ELEMENTS]
 - properties: 0x3e0a080406e9 <FixedArray[0]> {
    #x: 100 (const data field 0)
    #y: 200 (const data field 1)
 }
 
 DebugPrint: 0x3e0a080c60cd: [JS_OBJECT_TYPE]
 - map: 0x3e0a08284ce9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - prototype: 0x3e0a08241395 <Object map = 0x3e0a082801c1>
 - elements: 0x3e0a080406e9 <FixedArray[0]> [HOLEY_ELEMENTS]
 - properties: 0x3e0a080406e9 <FixedArray[0]> {
    #x: 3 (const data field 0)
    #y: 4 (const data field 1)
 }

重新構建隱藏類

  1. 物件建立好後新增新的屬性
  2. 物件建立好後刪除屬性

let point = {};
%DebugPrint(point);
point.x = 100;
%DebugPrint(point);
point.y = 200;
%DebugPrint(point);


 d8 --allow-natives-syntax test.js 
 
 
DebugPrint: 0x986080c5b35: [JS_OBJECT_TYPE]
 - map: 0x0986082802d9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - ...


DebugPrint: 0x986080c5b35: [JS_OBJECT_TYPE]
 - map: 0x098608284ce9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - ...
 - properties: 0x0986080406e9 <FixedArray[0]> {
    #x: 100 (const data field 0)
 }


DebugPrint: 0x986080c5b35: [JS_OBJECT_TYPE]
 - map: 0x098608284d11 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - p
 - ...
 - properties: 0x0986080406e9 <FixedArray[0]> {
    #x: 100 (const data field 0)
    #y: 200 (const data field 1) 

提升物件屬性的查詢效能,減少隱藏類的建立次數和儲存空間

  1. 使用字面量初始化物件時,要保證屬性的順序是一致的
  2. 儘量一次性初始化完整的物件屬性
  3. 儘量避免使用delete方法
// 順序不一樣,導致形狀不同,所以會建立不同的隱藏類
let point = {x:100,y:200};
let point2 = {y:100,x:200};

%DebugPrint(point);
%DebugPrint(point2);

 - map: 0x31d008284ce9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 
 - map: 0x31d008284d39 <Map(HOLEY_ELEMENTS)> [FastProperties]