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

为何两段ECMAScript随机打乱数组代码执行效果不同?

数组打乱代码执行效果差异解析

嘿,我来帮你理清楚这两段代码为啥执行效果完全不一样——核心问题出在是否真正修改了原数组的元素上:

第一段代码:看似交换,实则没碰原数组

先把代码格式化得更易读:

function randomize(arr){ 
  for(var i = 0; i < arr.length; i++){ 
    const random = Math.floor(Math.random()*arr.length); 
    // 把数组元素的值复制到临时变量里
    let temp = arr[i]; 
    let newR = arr[random]; 
    // 交换的只是两个临时变量的值,和原数组无关!
    [temp, newR] = [newR, temp]; 
  } 
  return arr; 
} 
console.log(randomize([1,2,3,4,5]));

这里的关键是:temp和newR是原数组元素值的副本(因为数组里存的是数字这种原始类型,赋值时会直接复制值)。你交换这两个临时变量,就像把盘子里的两个蛋糕拿出来换了个手,但根本没放回盘子里——原数组的元素位置从头到尾都没变化。所以这段代码执行后,输出的数组几乎和输入完全一致。

第二段代码:真正交换了数组元素位置

再看这段格式化后的代码:

function randomize(arr){ 
  for(var i = 0; i < arr.length; i++){ 
    const random = Math.floor(Math.random()*arr.length); 
    // 直接操作数组的索引,交换两个位置的元素本身
    [arr[i], arr[random]] = [arr[random], arr[i]]; 
  } 
  return arr; 
} 
console.log(randomize([1,2,3,4,5]));

这里是直接针对数组的索引位置进行操作:arr[i]和arr[random]指向的是数组里的具体元素位置,交换它们就相当于直接在盘子里把两个蛋糕换了位置,原数组自然会被修改,也就实现了打乱数组的效果。

小补充:顺便提一句,第二段的洗牌方式其实不是完全公平的(属于有偏洗牌),如果要实现无偏的随机打乱,推荐用标准的Fisher-Yates洗牌算法,但这是额外的知识点啦~

内容的提问来源于stack exchange,提问作者buzz eclair

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:23:40