javascript递归调用function向scope外数组push新值的时候为什么会同时改变整个数组的值?
我本来想用javascript写一段程序,把兼并在一起的一行数据扩展成多行数据。比如下面这一行
[["a1","a2","a3","a4","a5","a6","a7"],["b1","b2","b3","b4","b5"],["c1","c2","c3"]]
我希望输出成
[ [ 'a1', 'b1', 'c1' ],
[ 'a1', 'b1', 'c2' ],
[ 'a1', 'b1', 'c3' ],
[ 'a1', 'b2', 'c1' ],
...
[ 'a7', 'b5', 'c1' ],
[ 'a7', 'b5', 'c2' ],
[ 'a7', 'b5', 'c3' ] ]
大致写了一下程序:
function tableDecompress(t){
// var t = [["a1","a2","a3","a4","a5","a6","a7"],["b1","b2","b3","b4","b5"],["c1","c2","c3"]]
var xecimal = t.map(function(e,i,a){
if(i<a.length-1){
return xecimalCalc(a.slice(i+1))
}else{
return 1
}
})
function xecimalCalc(arr){
return arr.map(e=>e.length).reduce((a,b)=>a*b)
}
var ttlCell = xecimalCalc(t)
var result= new Array(ttlCell)
result.fill([])
fillIt(t,0,[],[])
function fillIt(arrOutter,iOutter,valueStore,addr){
arrOutter[iOutter].forEach(function(e,i,a){
var vStore = valueStore
var addrS = addr
vStore[iOutter]=e
addrS[iOutter]=i
if(iOutter<arrOutter.length-1){
fillIt(arrOutter,iOutter+1,vStore,addrS)
}else{
addrSeq = addrS.map((e,i)=>e*xecimal[i]).reduce((a,b)=>a+b)
result[addrSeq]=result[addrSeq].concat(vStore)
}
})
}
return result
}
这里面:
function xecimalCalc(arr){
return arr.map(e=>e.length).reduce((a,b)=>a*b)
}
var ttlCell = xecimalCalc(t)
var result= new Array(ttlCell)
result.fill([])
是我后面改过来的,原先就只是声明一个var result=[]
,在fillIt这个函数里面else分支直接result.push(vStore)
,但是如果这样做的话呢,就会变成下面的结果:
[ 'a7', 'b5', 'c3' ],
[ 'a7', 'b5', 'c3' ] ,
[ 'a7', 'b5', 'c3' ] ,
[ 'a7', 'b5', 'c3' ]
....
[ 'a7', 'b5', 'c3' ] ]
在else分支里面我试过console.log(vStore)
,还把addrS也算出来了,觉得这样子总不会重复覆盖了吧,但是仍旧不是那么回事。只有当我事先建好一个刚好够长的数组,把这个数组用[]填充好,之后不用赋值而是用concat的时候才能正常运行。
实在是搞不懂到底为啥会这样?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
多谢评论里的指点。所以问题是出在这两行代码:
对object用赋值只能是传递一个reference,要想做clone需要用下面的方法:
修改以后可以正常运行。