Object.keys() 使用会引发的问题

Object.keys()返回的顺序是什么?

我们理解的 Object.keys()总是会按照实际创建属性的顺序返回

当key为字符串时候,返回

let test = {
      a: 1,
      b: 2,
      d: 4,
      c: 3,
    }
    console.log(Object.keys(test))
    // 输出[ 'a', 'b', 'd', 'c' ]

把key换成浮点数,结果如下

let test = {
	  '1.0': 1,
	  '2.0': 2,
	  '4.0': 4,
	  '3.0': 3,
	}
	console.log(Object.keys(test))
	// 输出 [ '1.0', '2.0', '4.0', '3.0' ]

把key换成正整数,结果如下

 let test = {
	  [1]: 1,
	  [2]: 2,
	  [4]: 4,
	  [3]: 3,
 }
	console.log(Object.keys(test))
	// 输出 [ '1', '2', '3', '4' ]

把key换成浮点数和正整数组合,结果如下:

let test = {
	  '1.0': 1,
	  [2]: 2,
	  '4.0': 4,
	  [3]: 3,
	}
   console.log(Object.keys(test))
   //输出 [ '2', '3', '1.0', '4.0' ]

通过上面的输出,总结出现象是如果key为字符串或者浮点数的时候,会按照创建属性的顺序返回,如果是正整数会按照从小到大的顺序返回。这种情况的产生的原因是什么?

Object.keys() 返回顺序与遍历对象属性时的顺序一样,调用的 [OwnPropertyKeys] 内部方法

根据 ECMAScript 规范,在输出 keys 时会先将所有 key 为数组索引类型(正整数)从小到大的顺序排序,然后将所有字符串类型(包括负数、浮点数)的 key 按照实际创建的顺序来排序。

V8 内部是如何处理对象属性的?

V8 在存储对象属性时,为了提高访问效率,会分为常规属性(properties) 和 排序属性(elements)

排序属性(elements) ,就是数组索引类型的属性(也就是正整数类型)。
常规属性(properties) ,就是字符串类型的属性(也包括负数、浮点数)。
以上两种属性都会存放在线性结构中,称为快属性。
然而这样每次查询都有一个间接层,会影响效率,所以 V8 引入对象内属性(in-object-properties) 。

V8 会为每一个对象关联一个隐藏类,用于记录该对象的形状,相同形状的对象会共用同一个隐藏类。

当对象添加、删除属性的时候,会创建一个新的对应的隐藏类,并重新关联。

对象内属性会将部分常规属性直接放在对象第一层,所以它访问效率是最高的。

当常规属性的数量少于对象初始化时的属性数量时,常规属性会直接作为对象内属性存放。

虽然快属性访问速度快,但是从线性结构中添加或删除时执行效率会非常低,因此如果属性特别多、或出现添加和删除属性时,就会将常规属性从线性存储改为字典存储,形成慢属性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值