咨询:为何JavaScript循环中变量赋值函数参数不重置,赋值数组则重置?
为什么JavaScript循环里数组变量的表现不一样?
这个问题的核心其实是JavaScript里引用类型和值类型的区别,尤其是数组作为引用类型的特性在搞鬼,我给你拆解清楚:
示例#1:变量不重置的原因
先把你的示例#1代码完整贴出来:
function almostIncreasingSequence(sequence) { for (var i = 0; i < sequence.length; i++) { var testArray = sequence; testArray.splice(i, 1); console.log(testArray); } } almostIncreasingSequence([1, 3, 2, 1]);
这里的关键在于:
- JavaScript里的数组属于引用类型,当你写
testArray = sequence时,并没有复制整个数组,只是把sequence指向的数组的内存地址复制给了testArray。简单说,testArray和sequence现在是“共用同一个数组”。 - 第一次循环执行
splice(i,1)时,直接修改了这个共享的数组;第二次循环时,原sequence已经是被修改过的状态了,testArray再指向它,自然是修改后的结果,根本不会“重置”。 - 你可以试试在循环里打印原
sequence,会发现它和testArray的输出完全一致,因为它们本来就是同一个东西。
示例#2:变量会重置的原因
虽然你没写完示例#2的代码,但根据描述,它肯定是每次循环都创建了一个全新的数组副本,比如类似这样的写法:
function almostIncreasingSequence(sequence) { for (var i = 0; i < sequence.length; i++) { // 每次都生成原数组的独立副本,而不是引用原数组 var testArray = [...sequence]; // 也可以用 sequence.slice() 或者 Array.from(sequence) testArray.splice(i, 1); console.log(testArray); } } almostIncreasingSequence([1, 3, 2, 1]);
这里的逻辑是:
[...sequence]、slice()这类方法会把原数组的元素逐个复制出来,创建一个完全独立的新数组对象,它和原sequence在内存里是两个毫不相干的东西。- 所以每次循环,
testArray都是一个和原数组一模一样的“新替身”,修改它不会影响原数组;下一次循环又会重新生成一个新替身,看起来就像是“每次迭代后重置”了。
一句话总结
- 直接赋值引用类型(数组、对象):两个变量共享同一个内存对象,改一个全变。
- 创建副本:每次都得到独立的新对象,修改互不影响,也就实现了“重置”效果。
内容的提问来源于stack exchange,提问作者matkoson
相关产品推荐
相关产品推荐

