javasctipt 向数组中传送变量引出的问题
程序中传递参数用到一个数组,在构造数组过程中出了点情况。
向参数数组中传送的变量是从另外一个数组中提取,装满6个数据之后,开始调用函数时行运算。
起初的代码这样:
let picCount = this.state.heads.length - 1; //全部数据的长度
let idx = 1; //控制数组长度的临时变量
let nms = []; //准备作为参数的一个二维数组
let pic = []; //临时变量数组,准备往数组里送。
for(; picCount >= 0 ;picCount --){
pic[0] = this.state.heads[picCount].tid;
pic[1] = this.state.heads[picCount].tname;
//下面两句分别试过,不管是用push的方法,还是直接用数组下标访问,都会出现同样的问题。
nms.push(pic);
nms[idx-1]=pic;
idx ++;
if(idx > 6 || picCount === 0){ //凑够6个数据,或者全部数据已经完成
this.getPicLine(nms); //以刚生成的数组作为参数调用函数
nms = []; //清空数组
idx = 1; //恢复临时变量
}
}
实际运行中发现,这段代码生成的参数数组6个元素内容完全一样。通过中间变量输出显示发现,从原始数组中提取出来的变量正常,每一次的pic变量正常,但nms数组的内容随着每一次pic的写入在发生变化。
每一次写入之后,之前的元素全都会变成最后一次写入的元素。
想了好久不知道问题出在哪里。
后来请教了别人,把 let pic = []; 放到循环里面。这样一试果然正常了。
把这个过程分析一下,对javascript的认识又加深一层,这个问题关系到javascript对系统资源的管理。
javascript的一个变量在它生命周期里被赋值给其它变量的时候,新变量并没有装入真正的数据,它只是原始变量的一个影子。用C语言的思想来理解,新变量就是一个指针,它被赋予的是原始变量的地址。
javascript这样做的目的是为了减小系统资源的开销。可这样做的结果就是原始变量发生改变,被赋值的变量全都改变。于是就产生了本文一开始的现象。
把 let pic = [] 放在循环之外,整个代码都是它的生命周期,只有一个pic变量存在,每次放进参数数组的只是pic的地址,pic变了,数组里的元素也就会都发生变化。
放进循环之后,每一次用的都是一个新的pic,就没有原始代码的问题了。
为了避免上面的问题,在向参数数组赋值的时候可以直接传递数据,不用变量,按下面的写法:
nms.push([pic[0],pic[1]]);
后来我直接连 pic 这个中间变量也省了,直接用原始变量:
nms.push([this.state.heads[picCount].tid,this.state.heads[picCount].tname]);
以前用惯了C之类的强类型语言,数据是数据,地址是地址,不同类型数据有不同操作方法,绝不能乱用。可在javascript这里对变量约束太宽松,什么都可以往变量里放,也没有什么值,地址之类的概念,表面上说是约束少了更方便,可实际上约束少了代码写的随便,更容易掉进坑里。

浙公网安备 33010602011771号