本文探讨JavaScript中Object对象的key遍历顺序。根据ES6规范,整数键(含整数字符串)按数值大小升序排列,非整数键保持创建顺序。若混合存在,整数键优先于非整数键。文章提供了通过字符串后缀或前缀转换key以强制排序的实用技巧,并结合Vue示例解决下拉列表排序问题。
Object遍历顺序问题背景
在使用for/in循环遍历Object对象时,输出的结果是否严格遵循key的添加顺序?
结论是:并不一定。
背景
近期在项目开发中,我遇到了一个具体需求:
下拉列表包含三个固定选项:-1代表全部,0代表正常,1代表失效。
为此,我定义了一个对象,并通过循环该对象将数据渲染到<option>标签中:
var obj = {
'-1': '全部',
'0' : '正常',
'1' : '失效'
};
<!-- Vue代码片段 -->
<select>
<option v-for="(item, key) in obj" :value="key">{{item}}</option>
</select>
<!-- 结果却是: -->
<!-- 0 正常 -->
<!-- 1 失效 -->
<!-- -1 全部 -->
这引出了本文的核心问题,请看后续分析。
Object键值排序规则详解
解惑
Object的key究竟遵循怎样的排序规则?答案是:
若key为整数(如123)或整数类型的字符串(如“123”),则按数值从小到大排序;其他数据类型则严格按照对象key的实际创建顺序排列。
var obj = {
'-1': '全部',
'0' : '正常',
'1' : '失效'
};
for (let key in obj) {
console.log(key, obj[key]);
};
// result
// 0 正常
// 1 失效
// -1 全部
此外,若key中同时包含整数/整数字符串与其他数据类型,整数键会排在非整数键之前。例如:
var obj = {
'a': 111,
'我' : 222,
'1' : 333,
'1.3': 444,
'3': 555
};
for (let key in obj) {
console.log(key, obj[key]);
};
// result
// 1 333
// 3 555
// a 111
// 我 222
// 1.3 444
强制保持遍历顺序的解决方案
解决
针对上述场景,如何确保对象按key的顺序输出?答案是:
将key转换为非整数类型的字符串,在获取值时再还原为原始数值。
如果所有key均为类整数形式,可采用以下方法:
// 每个key后面加.转换成字符串
var obj = {
'-1.': '全部',
'0.' : '正常',
'1.' : '失效'
};
for (let key in obj) {
// ~~ 表示转换成整数,这样上面的key又还原成了-1/0/1
console.log(~~key, obj[key]);
};
// result
// -1 全部
// 0 正常
// 1 失效
但如果key包含多种数据类型,无法直接转为整数,则可采用以下策略:
// 每个key前面加.转换成字符串
var obj = {
'.a': 111,
'.我' : 222,
'.1' : 333,
'.1.3': 444,
'.3': 555
};
for (let key in obj) {
// 从第1个字符取原始的key
console.log(key.substring(1), obj[key]);
};
// result
// a 111
// 我 222
// 1 333
// 1.3 444
// 3 555
最后
回到最初的问题,解决方案如下:
var obj = {
'-1.': '全部',
'0.' : '正常',
'1.' : '失效'
};
<select>
<option v-for="(item, key) in obj" :value="~~key">{{item}}</option>
</select>
参考
Objects#ordered-like-an-object
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。