You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何forEach循环为Audio数组赋值src时所有元素均被修改?求助

遍历数组为Audio对象赋值src时所有元素属性同步变化的问题

问题描述

我想遍历字符串数组,将每个字符串赋值给对应Audio对象的src属性,让每个Audio对象拥有唯一的音效路径。但运行代码后发现,所有Audio元素的src都会被设置成最后一次迭代的路径,而非各自对应的值。

我的代码如下:

const srcArr = ['sounds/crash.mp3', 'sounds/kick-bass.mp3', 'sounds/snare.mp3', 'sounds/tom-1.mp3', 'sounds/tom-2.mp3', 
'sounds/tom-3.mp3', 'sounds/tom-4.mp3'];
const audios = new Array(srcArr.length).fill(new Audio());

audios.forEach((audio, index) => {
    audio.src = srcArr[index];
});

错误原因

问题不在forEach循环的机制上,你的forEach理解是对的——它确实会遍历数组每个元素并传入当前对象和索引。真正的问题出在**Array.fill()的使用上**:

当你执行new Array(srcArr.length).fill(new Audio())时,new Audio()只会执行一次,创建单个Audio实例。数组里的所有元素都是这个实例的引用,也就是说audios[0]到audios[6]指向的都是同一个内存地址里的Audio对象。所以你在forEach里修改任何一个元素的src,本质上都是在修改同一个对象的属性,最终所有元素的src都会变成最后一次赋值的结果。

正确写法

需要为数组的每个位置单独创建Audio对象,避免复用同一个实例,以下几种方式都可以:

方式1:使用map方法直接生成数组

const srcArr = ['sounds/crash.mp3', 'sounds/kick-bass.mp3', 'sounds/snare.mp3', 'sounds/tom-1.mp3', 'sounds/tom-2.mp3', 
'sounds/tom-3.mp3', 'sounds/tom-4.mp3'];
const audios = srcArr.map(src => new Audio(src));

方式2:用forEach循环手动创建并添加

const srcArr = ['sounds/crash.mp3', 'sounds/kick-bass.mp3', 'sounds/snare.mp3', 'sounds/tom-1.mp3', 'sounds/tom-2.mp3', 
'sounds/tom-3.mp3', 'sounds/tom-4.mp3'];
const audios = [];
srcArr.forEach(src => {
  audios.push(new Audio(src));
});

方式3:用for循环初始化数组

const srcArr = ['sounds/crash.mp3', 'sounds/kick-bass.mp3', 'sounds/snare.mp3', 'sounds/tom-1.mp3', 'sounds/tom-2.mp3', 
'sounds/tom-3.mp3', 'sounds/tom-4.mp3'];
const audios = new Array(srcArr.length);
for (let i = 0; i < srcArr.length; i++) {
  audios[i] = new Audio(srcArr[i]);
}

总结

forEach循环的逻辑是正确的,问题源于对fill方法处理引用类型的特性不熟悉——fill对于对象、数组这类引用类型,只会复制引用而不会创建新实例。只要确保每个数组元素都是独立的Audio对象,就能实现预期效果。

内容的提问来源于stack exchange,提问作者Caleb Renfroe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 17:02:43