关于js中for...in循环对象时,输出key值顺序混乱问题

这篇具有很好参考价值的文章主要介绍了关于js中for...in循环对象时,输出key值顺序混乱问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

解决循环复杂对象,key值顺序混乱

问题描述

当循环纯数字索引对象时,循环key值是正确的

js 循环对象key,javascript,前端,开发语言

当对象变为复杂对象时,输出的key就变得复杂

js 循环对象key,javascript,前端,开发语言

解决方案

//循环中使用
for(let item in this.objectOrder(data)){
	this.objArr.push(item)
}
 
//方法
objectOrder(obj) {//排序的函数
	var newkey = Object.keys(obj).sort(); //先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组
	var newObj = {};//创建一个新的对象,用于存放排好序的键值对
	for (var i = 0; i < newkey.length; i++) {//遍历newkey数组
	    newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
	}
	return newObj;//返回排好序的新对象
}

js 循环对象key,javascript,前端,开发语言

循环对象时,输出key值顺序混乱原因

ES6之前,循环对象常见做法是使用:for…in。但是for…in循环的问题在于它会遍历原型链中的属性,所以需要使用hasOwnProperty执行检查属性是否属于该对象。

ES6之后,我们对于对象的循环有了更好的办法:

  • Object.keys(创建一个包含对象所有属性的数组),
const fruits ={
    appple:22,
    pear:34,
    orange:88
}
var keys = Object.keys(fruits);
console.log(keys);  //["appple", "pear", "orange"]
  • Object.values(创建一个数组,其中包含对象中每个属性的值),
const fruits ={
    appple:22,
    pear:34,
    orange:88
}

var values =Object.values(fruits);
console.log(values); //[22, 34, 88]
  • Object.entries(创建了一个二维数组,每个内部数组都有2个元素,第一个元素是属性名,第二个属性值)
const fruits ={
    appple:22,
    pear:34,
    orange:88
}
var entries = Object.entries(fruits);
console.log(entries);
// [['appple',22],['pear',34],['orange',88]]
const fruits ={
    appple:22,
    pear:34,
    orange:88
}
for (const [fruit,num] of entries) {
    console.log(`we have ${num} ${fruit}`);  //we have 22 appple ...
}

Object对应的方法也存在相同的问题,可以使用类似的方法进行修改

下面主要说的是 for…in

循环对象时,顺序为什么会乱?

1.这本身就是一个ECMA的一个规范,数字按升序输出,字符串按创建顺序输出,并且数字优先级高于字符串
2.JS本身是不能被计算机识别,需要通过V8转化为字节码
3.那么针对ECMA的一个规范,v8对这个规范做的优化策略
4.排序属性 elements,用来存储数字。 常规属性 properties 用来存储字符串。为了优化,引入对象内属性
5.对象属性多后,会采用慢属性来存储数据,快属性就是采用线性数据结构,慢属性就是采用非线性结构,比如字典来存储数据。

1. 先遍历出整数属性(integer properties,按照升序),然后其他属性按照创建时候的顺序遍历出来。

  • 整数属性
String(Math.trunc(Number(prop)) === prop

当上面的判断结果为 true,prop 就是整数属性,否则不是。

例:

"49" 是整数属性,因为 String(Math.trunc(Number('49')) 的结果还是 "49"。
"+49" 不是整数属性,因为 String(Math.trunc(Number('+49')) 的结果是 "49",不是 "+49"。
"1.2" 不是整数属性,因为 String(Math.trunc(Number('1.2')) 的结果是 "1",不是 "1.2"。

「数字属性应该按照索引值⼤⼩升序排列,字符串属性根据创建时的顺序升序排列。并且数字属性优先于字符串」

2. 首先JS代码本身是不会直接被计算机执行,计算机只能接收二进制的汇编代码,所以,中间需要一层转化,而这个转化,在chrom就是v8引擎

在v8 里是怎么样存储和读取对象属性的呢,

1. 在v8里,将对象里的属性,分为两大类。数字类型,叫排序属性,在v8里叫elements。字符串类型,叫常规属性,在v8里叫properties。
在v8里,为了有效的存储和访问这对象属性,分别使用两个线性结构来保存这两个属性。

2. 在elements对象中,会按照顺序存放排序属性,properties属性则指向了properties对 象,在properties对象中,会按照创建时的顺序保存了常规属性。

3. 但是这样也存在一个问题,在查找排序属性时,直接通过索引即可。但是对象,需要找到properties,然后找到propteries里的属性,这样无疑多了一层操作,所以引入了一个新名词 对象内属性( in- object properties)

4. 但是常规属性也有个数限制,超过是个,默认是10个,就要开辟新的空间来保存常规属性

针对数量少的对象属性,采用以上策略完全没有问题,但是对象数量多了以后,会采用排序非线性字典结构来存储

  • 线性结构:是一个有序数据元素的集合。常见线性结构, 线性表,栈,队列,双队列,串(一维数组)
  • 非线性结构: 其逻辑特征是一个结点元素可能有多个直接前驱和多个直接后继。

那这个时候,通过线性结构来存储数据,查找肯定的快的,但是如果涉及到大量的修改数据,那么动一发而牵全身,是非常耗性能的,所以数据多了,v8采用了慢排序

  • 快排序: 采用线性结构
  • 慢排序:采用非线性结构 ,比如字典

3. 同时与浏览器有关系,Chrome跟IE是不一样的,所以给出以下结论:

Chrome Opera 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版规范。因此,使用 for-in 语句遍历对象属性时遍历书序并非属性构建顺序。
而 IE6 IE7 IE8 Firefox Safari 的 JavaScript 解析引擎遵循的是较老的 ECMA-262 第三版规范,属性遍历顺序由属性构建的顺序决定。

Chrome Opera 中使用 for-in 语句遍历对象属性时会遵循一个规律:
它们会先提取所有 key 的 parseFloat 值为非负整数的属性,然后根据数字顺序对属性排序首先遍历出来,然后按照对象定义的顺序遍历余下的所有属性。

https://blog.csdn.net/wk15038187622/article/details/104062244文章来源地址https://www.toymoban.com/news/detail-627948.html

到了这里,关于关于js中for...in循环对象时,输出key值顺序混乱问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue for循环不建议使用index作为key的原因

    先看下面一个例子: 当点击按钮时,会删除数组第二个数据,这样就会导致原数组第二个数据之后数据的index发生改变,从而导致person3,和person4节点的更新,增加了额外的性能开销; 如果将key由绑定index改为绑定id,上述性能开销的问题就不会存在,因为更换key绑定时,删除

    2024年02月02日
    浏览(38)
  • js遍历对象key,value

    方法一:转化为操作数组forEach遍历 遍历对象属性 关于Object.keys()方法 Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致。 例子 遍历对象属性值 关于Object.values()方法 object .values()静态方

    2024年02月11日
    浏览(43)
  • RuntimeError: Error(s) in loading state_dict for ..:Missing key(s) in state_dict: …Unexpected key...

    原因:预训练权重层数的键值与新构建的模型中的权重层数名称不吻合,Checkpoint里面的模型是在双卡上训练的,保存的key 前面都多一个module. 解决:model = torch.nn.DataParallel(model, device_ids=[0, 1]).cuda() torch.nn.DataParallel 是一种能够将数据分散到多张显卡上从而加快模型训练的方法

    2024年01月21日
    浏览(45)
  • 无涯教程-Javascript - For...in循环语句

    for ... in 循环用于循环访问对象的属性,由于无涯教程尚未讨论 Objects 对象,您就会发现此循环非常有用。 “ for...in”循环的语法为: 在每次迭代中,将 object 对象中的一个属性分配给 variablename 变量,此循环一直进行到对象的所有属性。 请尝试以下示例来实现\\\" for-in\\\"循环,它

    2024年02月16日
    浏览(40)
  • js判断对象是否拥有某个key

    方法一 : \\\"key\\\" in obj ,结果为 false,表示不包含;否则表示包含 方法二 : obj.hasOwnProperty(\\\"key\\\") ,obj 表示对象,结果为 false 表示不包含;否则表示包含 这两种方法都可以用于检查对象是否包含指定的属性,但它们有一些区别。 “key” in obj: 这种方法使用 in 运算符来检查属

    2024年02月08日
    浏览(63)
  • (vue)获取对象的键遍历,同时循环el-tab页展示key及内容

    效果: 数据结构: 代码:

    2024年02月13日
    浏览(39)
  • matlab中的foreach、for in 循环、迭代器

    I 是个行向量,对于行向量,可以像上面的语法那样在 for 循环中使用,遍历 I 中的每一个元素。 如果 I 是列向量,就不行了。 可以看到 a 直接被赋值成整个列向量。 可见,for 循环中被用来迭代的矩阵会被看成只有一行,里面的元素是一个个列向量,for 循环一次取出里面的

    2024年02月11日
    浏览(46)
  • for循环的输出控制(输出1-100中的奇数、偶数、倍数以及公倍数)

    一、输出1-100中所有的奇数: i = 1 while i = 100:     if i%2 == 1:         print(i)     i += 1   法二: for i in range(1,101):     if i%2 == 1:         print(i)   法三: for i in range(1,101,2):     print(i)     二、输出1-100中所有的偶数: for i in range(1,101):     if i % 2 == 0:         print(i)   三、

    2024年02月08日
    浏览(37)
  • 数组的5种遍历(for循环、for...in、for...of、forEach()、map()

    数组:内存中一块连续的存储单元,这些存储单元具有共同的名称,不同的索引(下标)。 数组5种遍历: 1、for循环        任何数组都可以使用for循环进行遍历,使用频率最高                                 for (let i = 0; i arr.length; i++) {                            

    2024年02月06日
    浏览(46)
  • js如何遍历对象的key和value

    在JavaScript中,可以使用for…in循环来遍历对象的键(key)和值(value)。以下是一个示例: 在这个例子中,for…in循环会遍历对象obj的所有键。然后,hasOwnProperty函数会检查这个键是否是对象obj自身的一个属性,而不是从其原型链继承的。如果是对象自己的属性,就输出这个键

    2024年02月10日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包