Javascript while 循环奇怪的行为
Javascript while loop strange behaviour
下面的代码块应该控制台记录数组 ('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
。或者,对于 me(并且您的里程可能会有所不同),当我 运行 上面的第一个片段实际上向我展示时,让控制台 open数组的静态副本(是的,真的)。
示例:
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));
...但是当然,如果数组中有对象,两个数组将引用同一个对象,所以您仍然可能有动态问题。
正如其他人在 chrome 中所说,console.log
函数异步工作,因此有时在使用 console.log
后对变量的更改将反映在日志中。我总是使用
打印对象
console.log(JSON.stringify(arr));
这将在打印时保持数组或对象的结构。
或者复制数组
console.log(arr.slice(0));
下面的代码块应该控制台记录数组 ('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
。或者,对于 me(并且您的里程可能会有所不同),当我 运行 上面的第一个片段实际上向我展示时,让控制台 open数组的静态副本(是的,真的)。
示例:
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));
...但是当然,如果数组中有对象,两个数组将引用同一个对象,所以您仍然可能有动态问题。
正如其他人在 chrome 中所说,console.log
函数异步工作,因此有时在使用 console.log
后对变量的更改将反映在日志中。我总是使用
console.log(JSON.stringify(arr));
这将在打印时保持数组或对象的结构。
或者复制数组
console.log(arr.slice(0));