You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript数组索引访问返回undefined及控制台提示问题解析

问题:数组push元素后,console.log(array)能看到元素但array[0]返回undefined,以及控制台蓝色提示的含义

我创建了一个数组array,通过array.push()方法向其中插入元素。执行console.log(array)时能看到对应输出,但执行console.log(array[0])却返回undefined。请问这是什么原因?另外截图中的蓝色提示“this value was evaluated on first expanding it may have changed since then in array javascript”是什么意思?


完整代码

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>zip reader</title>
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.3/jstree.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<body>
    <h3>Choose the local(s) zip file(s)</h3>
    <input type="file" id="file" name="file" multiple /><br />
    <div id="result_block" class="hidden">
        <h3>Content :</h3>
        <div id="result"></div>
    </div>
</body>
<script src="jszip.min.js"></script>
<script src="jszip-utils.min.js"></script>
<script src="app1.js"></script>
<script src="FileSaver.min.js"></script>
</html>

app1.js

var array = []
var contents = []

var $result = $("#result");
$("#file").on("change", function(evt) {
    // 清空内容
    $result.html("");
    // 显示结果区块
    $("#result_block").removeClass("hidden").addClass("show");

    // 处理单个文件的闭包函数
    function handleFile(f) {
        var $title = $("<h4>", {
            text : f.name
        });
        var $fileContent = $("<ul>");
        $result.append($title);
        $result.append($fileContent);
        
        var dateBefore = new Date();
        JSZip.loadAsync(f)                                   // 异步读取Blob文件
            .then(function(zip) {
                var dateAfter = new Date();
                $title.append($("<span>", {
                    "class": "small",
                    text:" (loaded in " + (dateAfter - dateBefore) + "ms)"
                }));

                zip.forEach(function (relativePath, zipEntry) { 
                    var y = zipEntry.name
                    array.push(y);

                    $fileContent.append($("<li>", {
                        text : zipEntry.name
                    }));
                });
            }, function (e) {
                $result.append($("<div>", {
                    "class" : "alert alert-danger",
                    text : "Error reading " + f.name + ": " + e.message
                }));
            });
    }

    var files = evt.target.files;
    for (var i = 0; i < files.length; i++) {
        handleFile(files[i]);
    }
    console.log(array[0])
});

问题解答

1. 为什么console.log(array[0])返回undefined

核心是异步代码的执行顺序问题:

  • JSZip.loadAsync(f)是异步方法,它会在后台加载解析Zip文件,不会阻塞后续代码运行。
  • 当循环结束后执行console.log(array[0])时,JSZip.loadAsync的then回调还未触发,array.push(y)根本没执行过,此时array是空数组,array[0]自然为undefined。
  • 而当你在控制台手动展开console.log(array)的输出时,浏览器已经完成了Zip文件解析,then回调已执行并向数组插入了元素,所以能看到内容。

2. 控制台蓝色提示的含义

提示翻译为:此值是在首次展开时计算的,此后该值可能已发生变化

  • 浏览器控制台对于数组、对象这类引用类型,不会在调用console.log时立即打印所有内容,而是保存一个指向该对象的引用。
  • 当你手动展开数组时,浏览器才会读取它当前的实际内容。如果在console.log执行之后,数组被异步代码修改,就会出现这个提示,说明你看到的内容和console.log执行时的原始内容不一致。

内容的提问来源于stack exchange,提问作者gaurav joshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:36:32