JavaScript控制台在分配变量之前打印变量的分配值?

JavaScript控制台在分配变量之前打印变量的分配值?,javascript,Javascript,我对JavaScript或Chrome控制台的行为深感困惑。有人能帮我理解吗 基本上,我有以下JavaScript代码,没有嵌套在任何函数或其他作用域中: var initial_array = []; function initialiseArray() { initial_array = [2, 9, 8, 6, 0, 2, 1]; } function copyToNewArray() { var copied_array = []; console.log

我对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();
var初始数组=[];
函数initialiseArray(){
初始_数组=[2,9,8,6,0,2,1];
} 
函数copyToNewArray(){
var\u数组=[];
log(“复制1”,复制的数组);
对于(变量i=0;i
我希望
COPIED 1
打印
[]
,因为变量尚未赋值,但它会打印
[2,9,8,6,0,2,1]
,即赋值后的值

为什么?

顺便说一句,如果将第8-11行替换为
initial\u array=copied\u array
,则
RESULTS 1
确实会打印为
[]
。这与使用
.push
有关吗?

var initial_array=[];
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();
函数initialiseArray(){ 初始_数组=[2,9,8,6,0,2,1]; } 函数copyToNewArray(){ var\u数组=[]; log(“复制1”,复制的数组); 警报(复制的数组长度); 对于(变量i=0;i
添加行
警报(复制的数组长度)将显示正确的结果


发生的情况是日志与javascript执行不同步。日志打印时,值已经更改。

这是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();

控制台实际上是异步的。因为您正在记录一个对象的引用,所以在记录该对象时,它已经发生了更改


您可以在记录阵列之前对其进行克隆,以确保在记录阵列之前不会对其进行更改。

由于阵列是通过引用传递的,因此对其所做的每一次更改都将更改控制台中的输出。这部分是Chrome控制台的行为,部分是JavaScript的行为

如果要在调用
console.log
时打印结果,可以使用
JSON.stringify
将其作为字符串输出

console.log("COPIED 1", JSON.stringify(copied_array));
重要编辑


看来我大错特错了。正如diEcho在问题的评论中指出的那样,a有a。这似乎只是Chrome的行为。

这是因为
复制的数组是一个引用,并且console.log是异步执行的,因此在第一个日志打印之前修改数组的内容

您可以在打印之前复制阵列

console.log([].concat(copied_array));

尝试在Chrome脚本调试器中调试您的问题。在行上放置断点:

for (var i = 0; i < initial_array.length; i++) {
for(变量i=0;i
你会看到你想要的行为

您遇到的问题是,您错误地假设Chrome调试器在异步执行
控制台.log时会立即“打印”值。由于数组在实际打印值时在后端通过引用传递,因此现在就是您看到的数组。

控制台。日志(“复制的1”,JSON.stringify(复制的数组));

应该可以进行调试


这是您提到的一个BUG,请参见下文

也阅读类似的问题


如果您想保留控制台的功能,例如在数组中扩展对象,我建议使用
.slice
,这样可以创建一个在记录时不会更改的数组副本:

console.log("COPIED 1", copied_array.slice());

有趣。这似乎解决了同样的问题吗?类似的问题:不过,你会认为它会在适当的点渲染/字符串化/解析数组引用,否则
console.log
ing数组几乎不会工作。Firefox也会屈服于此,还是更智能?@LightnessRacesinOrbit:不是更智能,但是我不愿意将所有内容都转换为字符串,所以它应该可以工作。(另一方面,FireBug…我不确定。)我建议这是“更智能的”,因为在这种情况下,将引用绑定到这么晚显然违反了POLS。(FWIW,我的意思是说FireBug)复制为什么不使用
arr.slice()
?我在firefox web developer控制台(股票浏览器,而不是firebug)中也发现了这种行为。因此,这可能不仅仅是一种Chrome行为。Nice,还有JSON.stringify(复制的数组)方法似乎更好,我想。对于Chrome脚本调试器,这是一个很好的建议,我曾尝试使用Webstorm调试器,但没有多大成功。很好的答案…蹩脚的记录器:(
console.log("COPIED 1", copied_array.slice());