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));