生成含数组的对象时出现异常行为的技术求助
问题原因与解决方案
异常原因
JavaScript中数组属于引用类型,你在init函数里仅创建了一个pos数组,随后的循环只是把这个数组的引用重复赋值给data的每个键。也就是说,data[0]到data[15]指向的都是内存中同一个数组实例。所以修改任意一个属性对应的数组元素,所有关联该数组引用的属性都会同步变化。
解决方法
核心是给data的每个键分配独立的数组实例,避免复用同一个引用,以下是两种常用实现方式:
方式一:循环内创建新数组
将生成全0数组的逻辑放到循环内部,每次循环都创建一个全新的数组:
var data = {} function init() { for(var i = 0; i < 16; i++) { // 每次循环生成独立的全0数组 data[i] = Array.apply(null, Array(16)).map(Number.prototype.valueOf, 0); } } init(); data[0][1] = 1; console.log(data); // 仅data[0]的第二个元素为1,其余保持0
方式二:复制数组副本
如果希望保留外部创建数组的逻辑,可在赋值时通过slice()方法复制数组(该方法会返回原数组的新副本):
var data = {} function init() { var pos = Array.apply(null, Array(16)).map(Number.prototype.valueOf, 0); for(var i = 0; i < 16; i++) { // 复制数组生成新引用 data[i] = pos.slice(); } } init(); data[0][1] = 1; console.log(data); // 仅data[0]的第二个元素为1
ES6简化写法
如果环境支持ES6,可用Array(16).fill(0)更简洁地创建全0数组:
var data = {} function init() { for(var i = 0; i < 16; i++) { data[i] = Array(16).fill(0); } } init();
内容的提问来源于stack exchange,提问作者HardGroove
相关产品推荐
相关产品推荐

