1、问题描述:现有如下数组:var ary = [ {'id':'1','qty':'5'}, {'id':'4','qty':'1'}, {'id':'2','qty':'3'}, {'id':'3','qty':'2'} ];需要根据数组元素中的qty属性将数组处理成如下数组:意即根据元素qty属性值来复制出相应个数的元素,复制出的元素qty属性值为“1”,原元素的qty属性值也为“1”。根据自己的思路使用for循环的最终代码如下:var ary = [ {'id':'1','qty':'5'}, {'id':'4','qty':'1'}, {'id':'2','qty':'3'}, {'id':'3','qty':'2'} ]; var ary2 = addAryFun(ary); console.log(ary2); function addAryFun(ary){ for(var i = 0;i<ary.length;i++){ if(parseInt(ary[i]['qty']) > 1){ for(var j = 1;j<parseInt(ary[i]['qty']);j++){ ary.splice(i,0,ary[i]); } ary[i]['qty'] = '1'; } } return ary; }但在addAryFun函数中使用for in循环数组却不能得到和for循环一样的结果,代码如下:var ary = [ {'id':'1','qty':'5'}, {'id':'4','qty':'1'}, {'id':'2','qty':'3'}, {'id':'3','qty':'2'} ]; var ary2 = addAryFun(ary); console.log(ary2); function addAryFun(ary){ //for in不能得到正确的结果: for(var i in ary){ if(parseInt(ary[i]['qty']) > 1){//for in循环在数组的第一个元素符合判断条件并执行了复制操作后就中断了,而for循环没有中断。 for(var j = 1;j<parseInt(ary[i]['qty']);j++){ ary.splice(i,0,ary[i]); } ary[i]['qty'] = '1'; } } return ary; }2、个人见解:不才愚见是for in循环在处理数组splice操作时存在问题,但由于使用for in循环数组这种方式只是自己的一时兴起,并不符合JS语义及规范,在网上也暂未搜索到类似情况,因此不知如何解释这一问题。故发表出来,希望有大神拨开云雾见青天。PS:重要的事情说三遍:使用for in循环数组只是自己一时兴起,并未也不会在实际项目中这样使用,addAryFun函数写得精简,希望大家就事论事,万望勿扩大战火,殃及池鱼,谢谢。
2 回答
天涯尽头无女友
TA贡献1831条经验 获得超9个赞
for(var i in ary){
console.log(i);//输出属性i
if(parseInt(ary[i]['qty']) > 1){//for in循环在数组的第一个元素符合判断条件并执行了复制操作后就中断了,而for循环没有中断。
for(var j = 1;j<parseInt(ary[i]['qty']);j++){
ary.splice(i,0,ary[i]);
}
ary[i]['qty'] = '1';
}
}
原本我以为是因为for...in循环会遍历其他枚举属性,但实际运行时并没有。
首先,加一句console.log(i);运行结束后发现i只输出0~3,正好是数组原来的长度。所以我判断在for...in循环中添加的属性在以后的遍历中可能被忽略了。
然后,我搜索了MDN,发现下面一段话:
在迭代进行时被添加到对象的属性,可能在之后的迭代被访问,也可能被忽略。通常,在迭代过程中最好不要在对象上进行添加、修改或者删除属性的操作,除非是对当前正在被访问的属性。
结论就是使用splice修改原数组后添加的属性会被忽略。至于怎么修改,我觉得好像没法改,只能说不要使用for...in吧。
添加回答
举报
0/150
提交
取消