以下代码块应控制台记录数组('abc'),然后进入 while 循环一次。在 while 循环中,第一个索引处的值应从“a”更改为“z”。 最后将返回数组。
但是,看起来数组甚至在进入循环之前就已更改,因为 console.log(arr) 生成 ["z", "b", "c"] 而不是 ["a", "b", "c"]。
function test(str){
var arr = str.split('');
var repeat = true;
console.log(arr);
while(repeat){
repeat = false;
arr[0] = 'z';
}
return arr;
}
console.log(test('abc'));
最佳答案
一些控制台实现(特别是 Chrome 的)会向您显示您记录的对象的半实时版本,而不是它的时间点副本。然后它会根据您在控制台中对它执行的操作而被卡住(并且在其他时候也是如此;我从来没有完全理解这些规则,并且它们因实现而异。)
复制您在 Chrome 上看到的内容的示例 - 在控制台关闭的情况下运行它,然后打开控制台查看结果:
function test(str){
var arr = str.split('');
var repeat = true;
console.log(arr);
while(repeat){
repeat = false;
arr[0] = 'z';
}
return arr;
}
console.log(test('abc'));
Run this with the console <strong>closed</strong>, then open it and look at the result.
这是我这样做后得到的结果,然后展开两个条目:
为了确保您看到的是静态副本,您可以这样做:
console.log(arr.join(", "));
...记录包含数组条目的字符串,而不是数组对象。或者您可以使用 JSON.stringify
而不是 join
。或者,对于我(你的情况可能会有所不同),当我运行上面的第一个代码片段时打开控制台实际上会显示数组的静态副本(是的,真的) .
示例:
function test(str){
var arr = str.split('');
var repeat = true;
console.log(arr.join(", "));
while(repeat){
repeat = false;
arr[0] = 'z';
}
return arr;
}
console.log(test('abc').join(", "));
或者制作数组的副本并记录副本:
示例:
function test(str){
var arr = str.split('');
var repeat = true;
console.log(arr.slice(0));
while(repeat){
repeat = false;
arr[0] = 'z';
}
return arr;
}
console.log(test('abc').slice(0));
...但是当然,如果数组中有对象,则两个数组将引用同一个对象,因此您仍然可能会遇到动态问题。
关于Javascript while 循环奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28325515/