V8 快属性与慢属性

8 篇文章 0 订阅
1 篇文章 0 订阅

快属性与慢属性

js对象是由一组组属性和值组成的集合,而js语言的角度来讲,js对象像一个字典,属性为键名,属性值为键值,通键名读取键值。

而 V8 实现对象存储时,并没有采用字典的存储方式,原因是字典的数据结构是非线性的,存取速度会比线性数据结构慢很多。

常规属性和排序属性

// 常规属性和排序属性
function Foo(){
    this[100] = '100';
    this[1] = '1';
    this['b']  = 'b';
    this[10] = '10';
    this['a'] = 'a';
    this[20] = '20';
}

const bar = new Foo();
for(key in bar){
    console.log(`key:${key} value: ${bar[key]}`)};

在这里插入图片描述

输出结果:在 chrome 浏览器中打开,发现属性的输出并不会按照定义的顺序来输出,number 类型的属性会先输出,并且 同类的 number 属性都按照数字大小升序输出的;string 类型的属性后输出,并且同类的string属性都按照定义顺序输出了。

之所以出现这样的结果,是因为在 ECMAScript 规范中定义了数字属性应该按照索引值大小升序排列,字符串属性根据 创建时的顺序升序排列。

在这里我们吧对象中的数字属性称为排序属性,在V8 中称为 elements, 字符串属性被称为常规属性,在 V8 中被称为 properties

在 V8 内部,为了有效地提升存储和访问这两种属性的性能,分别使用了两个线性数据结构 来分别保存排序属性和常规属性,具体结构如下图所示

在这里插入图片描述

通过上图我们发现,bar 对象包含了两个隐藏属性:elements 和 properties, elements 又指向了 elements 对象,elements 对象中,会按照 number 属性值升序排列, properties 也指向了 properties 对象, properties 对象中,则按照 属性创建顺序升序排列。

在执行属性检索操作时,先会遍历 elements 对象所有元素, 再去遍历 properties 对象的所有元素

虽然这样的存储方式,简化了程序的负责度,但是在查询元素时多了一步骤,比如查找 排序属性时,都要先通过对象的 element 属性找到 element 对象的地址,再从该对象中拿取,这也无疑影响了元素的查找效率。

快属性和慢属性

为了提升元素的查找效率,V8 将 对常规属性 properties 做了结构的修改,把一部分的常规属性直接写在了对象的本身,但是写在对象中的容量是有限制的,默认是10个,太多了会使对象变得臃肿,也会影响到查找效率。上述的做法减少了中间查询的一个步骤,提高了元素查询效率,V8 中把直接写在对象本身的属性称为对象内属性。而其他不能保存的对象内部的常规属性,依旧使用 properties 对象保存,但是这个 properties 对象的结构,不再是线性结构了,而是变成了非线性的树形结构,这样做的好处是, 树形结构可以**自由地扩容。**因此对象属性的存储结构变成了下图所示结构

在这里插入图片描述

通常,我们将保存在线性数据结构中的属性称为快属性,因为线性数据中只需要通过索引即可访问。而当常规属性过多时,就会把这些属性保存到 properties 对象的非线性数据中,我们将保存在非线性数据结构的属性称为 慢属性

在这里插入图片描述

ps:本笔记是阅读过李兵老师极客时间上发表的 《图解V8》的 快属性和慢属性 后所写的,侵权删。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值