最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 分析JS对象内部属性的遍历顺序

    正文概述 掘金(学过斯坦福大学人生设计课的前端小张)   2021-02-24   734

    背景

    在我们日常的开发中,有很多下拉选框里面的选项值是通过后端传回来的枚举值(enums)来作为渲染的数据的。例如这样子的下拉选框:
    分析JS对象内部属性的遍历顺序 如果我们需要让下拉选框里面的选项顺序,是依据后端返回的数据进行排序,那这个时候就有两种方法。一种是后端返回一个数组数据,然后我们按照顺序遍历这个数据数据。但如果是后端返回的是这样的一个对象,
    分析JS对象内部属性的遍历顺序 那我们就需要考虑一下Object.keys(), for ... in 等一系列的遍历对象的方法能否按照后端属性创建的顺序来输出了。

    问题重现

    我们先看一下下面这段代码:

    var obj = {
          name: 'abc',
          3: 'ccc',
          age: 23,
          class: 'first',
          hobby: 'basketball'
    };
    console.log(Object.keys(obj));
    // ["3", "name", "age", "class", "hobby"]
    

    可以看出,Object.keys()是无法保证输出的属性的顺序的。

    Object.keys不保证对象属性的顺序?

    在MDN-Object.keys中描述是这样的

    说是和手动遍历相同,那再看一下MDN-for..in

    最后一句表达了不同浏览器的实现方式是不同的。 但在一篇文章中描述Property order is predictable in JavaScript objects since ES2015
    分析JS对象内部属性的遍历顺序 根据文章重的描述是 Object.getOwnPropertyNames, Reflect.ownKeys他们都是内部通过ownPropertyKeys这个方法实现的,而且在文章中他还给出了对象中属性的输出顺序的规则

    Reflect.ownKeys()在IE中是不支持的 分析JS对象内部属性的遍历顺序

    Object.getOwnPropertyNames()的兼容性更好 分析JS对象内部属性的遍历顺序

    但如果是想用Object.keys,这个是否是基于ownPropertyKeys方法,还要根据浏览器实现而不同。

    标准参考

    根据 ECMA-262(ECMAScript)第三版中描述,for-in 语句的属性遍历的顺序是由对象定义时属性的书写顺序决定的。

    在现有最新的 ECMA-262(ECMAScript)第五版规范中,对 for-in 语句的遍历机制又做了调整,属性遍历的顺序是没有被规定的。

    经过上面问题重现的代码复现以及查阅网上的信息,Chrome Opera 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版规范。因此,使用 for-in 语句遍历对象属性时遍历顺序并非属性构建顺序。而 IE6 IE7 IE8 Firefox Safari 的 JavaScript 解析引擎遵循的是较老的 ECMA-262 第三版规范,属性遍历顺序由属性构建的顺序决定。

    Chrome的Object.keys的输出顺序以及原因分析

    Chrome 的 JS 引擎遍历对象属性时会遵循一个规律:

    它们会先提取所有 key 的 parseFloat 值为非负整数的属性,然后根据数字顺序对属性排序首先遍历出来,然后按照对象定义的顺序遍历余下的所有属性。例如下面的输出:

    let obj = {
        'b': 'testb',
        'a': 'testa',
        '1': 'test1',
        '测': 'test测',
        '2': 'test2'
    }
    
    console.log(Object.keys(obj));
    
    // [1, 2, 'b', 'a', '测']
    

    Chrome有这样的表现是因为V8引擎为了提高对象的访问速度,V8 里的对象就维护两个属性,会把数字放入线性的 elements 属性中,并按照顺序存放。会把非数字的属性放入 properties 中,不会排序。寻找属性时先 elements 而后在 properties。V8引擎这样做的原因可以在李兵老师的V8采用了哪些策略提升了对象属性的访问速度?中找到。 分析JS对象内部属性的遍历顺序

    总结

    我们目前的项目是只需要兼容Chrome浏览器即可,可以看出只要是数组的返回值里面,属性值的key不是数字与字符串混合用,那么完全可以使用Object.keys并且可以保证读取时的顺序的,保证下拉选项渲染的顺序,无需后端为此改为数组返回,后端也省去了把之前数据和代码全部更改的工作量和风险。

    引用

    为什么 JS 对象内部属性遍历的顺序乱了
    Object.keys(..)对象属性的顺序?
    Property order is predictable in JavaScript objects since ES2015
    js中关于for...in遍历对象属性的顺序问题


    起源地下载网 » 分析JS对象内部属性的遍历顺序

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元