我对JavaScript或Chrome控制台的行为感到非常困惑。有人可以帮我理解吗?
基本上我有以下JavaScript代码,而不是嵌套在任何函数或其他范围内:
var initial_array = [];
function initialiseArray() {
initial_array = [2, 9, 8, 6, 0, 2, 1];
}
function copyToNewArray() {
var copied_array = [];
console.log("COPIED 1", copied_array);
for (var i = 0; i < initial_array.length; i++) {
var copy = initial_array[i];
copied_array.push(copy);
}
console.log("COPIED 2", copied_array);
}
initialiseArray();
copyToNewArray();
我希望COPIED 1
打印[]
- 因为尚未分配变量 - 而是打印[2, 9, 8, 6, 0, 2, 1]
- 即分配后的值。
为什么呢?
顺便提一下,如果您将第8-11行替换为initial_array = copied_array
,则RESULTS 1
确实会打印为[]
。是否与使用.push
?
答案 0 :(得分:8)
尝试在Chrome脚本调试程序中调试您的问题。在这一行上设一个断点:
for (var i = 0; i < initial_array.length; i++) {
你会看到你想要的行为。
您遇到的问题是,您正在做出错误的假设,即Chrome调试器会立即'打印'该值,而实际上它是console.log
异步执行的。由于数组在实际打印值时会在后端通过引用传递,现在它就是您所看到的值。
答案 1 :(得分:3)
由于数组是通过引用传递的,因此您对其所做的每个更改都将更改控制台中输出的内容。部分是Chrome控制台的行为,部分是JavaScript的行为。
如果您想在调用console.log
时打印结果,可以使用JSON.stringify
将其输出为字符串。
console.log("COPIED 1", JSON.stringify(copied_array));
重要编辑
似乎我大多错了。正如 diEcho 在问题的评论中指出的那样,similar question有一个better answer。它似乎只是Chrome行为。
答案 2 :(得分:2)
console.log("COPIED 1", JSON.stringify(copied_array));
应该可以进行调试
这是你提到的BUG,见下文
https://bugs.webkit.org/show_bug.cgi?id=35801
也读过类似的问题
Is Chrome's JavaScript console lazy about evaluating arrays?
Bizarre console.log behaviour in Chrome Developer Tools
Why does javascript object show different values in console in Chrome, Firefox, Safari?
答案 3 :(得分:1)
这是数组在Chrome控制台中显示的方式,这是参考。如果您想要准确的结果,请转换为字符串:
var initial_array = [];
function initialiseArray() {
initial_array = [2, 9, 8, 6, 0, 2, 1];
}
function copyToNewArray() {
var copied_array = [];
console.log("COPIED 1", copied_array.toString());
for (var i = 0; i < initial_array.length; i++) {
var copy = initial_array[i];
copied_array.push(copy);
}
console.log("COPIED 2", copied_array.toString());
}
initialiseArray();
copyToNewArray();
你可以很容易地测试它:
var x = [];
console.log(x), x.push(5), x; // outputs [5] and [5]
答案 4 :(得分:1)
控制台实际上是异步的。因为您正在记录对象的引用,所以在记录对象时它已经发生了变化。
您可以在记录数组之前克隆该数组,以确保在记录之前它不会被更改。
答案 5 :(得分:0)
var initial_array = [];
function initialiseArray() {
initial_array = [2, 9, 8, 6, 0, 2, 1];
}
function copyToNewArray() {
var copied_array = [];
console.log("COPIED 1", copied_array);
alert(copied_array.length);
for (var i = 0; i < initial_array.length; i++) {
var copy = initial_array[i];
copied_array.push(copy);
}
console.log("COPIED 2", copied_array);
}
initialiseArray();
copyToNewArray();
添加第alert(copied_array.length);
行将显示正确的结果。
发生的事情是日志与javascript执行不同步。日志打印时,值已经更改。
答案 6 :(得分:0)
这是因为copied_array
是一个引用,并且console.log是异步执行的,所以在第一个日志打印之前修改了数组的内容。
您可以在打印前复制数组
console.log([].concat(copied_array));
答案 7 :(得分:0)
如果你想保持控制台的功能,例如在数组中扩展对象,我建议使用.slice
,它会生成一个在记录时不会改变的数组副本:
console.log("COPIED 1", copied_array.slice());