好玩的隐藏属性

隐藏类

  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]
posted @ 2021-06-18 17:07  pluscat  阅读(110)  评论(0编辑  收藏  举报