array.length 为零,但数组中有元素 [重复]

Posted

技术标签:

【中文标题】array.length 为零,但数组中有元素 [重复]【英文标题】:array.length is zero, but the array has elements in it [duplicate] 【发布时间】:2017-07-04 18:31:20 【问题描述】:

我目前正在练习使用电子,但我对 javascript 还是很陌生,我遇到了一个让我完全困惑的问题。我有以下代码:

    function getPaths() 
      var dirPath = document.getElementById("mdir").innerhtml;
      var filePaths = [];
      fs.readdir(dirPath, function(err, dir) 
        for(var i = 0, l = dir.length; i < l; i++) 
          var filePath = dir[i];
          filePaths.push(dirPath + "/" + filePath);
        
      );
      console.log(filePaths);
      console.log(filePaths.length);
    

它应该查看dirPath定义的目录,然后循环并获取该目录中所有文件的完整路径。它将它们附加到一个数组中,然后在底部将数组记录到控制台,然后是数组的长度。 令我困惑的是,鉴于该代码,数组按预期记录到控制台,但随后控制台将长度记录为零。我目前的想法是它与范围有关,但这没有意义,因为我在正在运行的函数上方的函数中声明了数组filePaths。除非我错过了什么。谁能指出我做错了什么?

【问题讨论】:

【参考方案1】:

readdir 是异步的。它不会马上得到结果。您应该在回调中使用filePaths。控制台显示该值的唯一原因是因为控制台会在您展开数组时对其进行评估。

当您按下左侧的小箭头时,将鼠标放在右侧的i 框上。发生的情况是控制台保留对数组的引用,因此当用户展开数组时,它会显示数组的当前值。但是当你登录 filePaths.length 时,数组是空的,因为 readdir 还没有读完,这就是你得到 0 的原因。但是当你打开控制台并按下那个箭头时,readdir 已经读完了并且控制台将打印数组的当前值(填充后)。

演示问题的示例:(不是解决方案,只是为了了解实际发生的情况)

打开浏览器控制台,试试这段代码,看看会发生什么:

var arr = [];

setTimeout(function() 
  arr.push(1, 2, 3);
, 5000);

console.log(arr.length);

console.log(arr);

这里的数组和它的长度都是在数组被填充之前记录的。数组将在 5 秒后填充。所以输出将是0 和数组array[] 的字符串表示。现在因为数组可能有大量数据,所以在用户展开数组之前控制台不会显示这些数据。所以控制台所做的是保持对数组的引用,直到用户按下展开箭头。如果您在 5 秒前展开数组,您会看到数组是空的(尚未填充)。如果您等到 5 秒过后再展开它,那么您会看到它已被填满,即使它被记录为一个空数组。

注意:此外,记录到控制台的行(类似于&gt; Array(0))只是记录发生时对象/数组的字符串表示形式。如果对象/数组发生变化,它将不会得到更新。所以有时也可能看起来confusing

我希望现在清楚了。

【讨论】:

我不建议使用setTimeout 函数,因为响应时间可能会因目录内容而有很大差异 @MaxZoom 我没有建议将setTimeout 作为解决方案!我只是用一个易于理解的例子解释了 OP 的问题,使用setTimeout 来强调问题的异步性! 好的,如果我做对了,我没有得到值的原因是因为 readdir 是异步的。结果,console.log() 在数组构建之前完成,结果它返回 0? @Taira 完全正确! readdir 只会在读取完成时注册要调用的回调,然后继续执行下一条语句并执行它(与 setTimeout) 发生的情况几乎相同)!如果您想要同步版本,请使用readdirSync(但我不推荐)。 好的,有道理!我来自 Python 的背景,所以这种类型的东西对我来说很陌生。不过还有一个问题:出于好奇,为什么不推荐readdirSync【参考方案2】:

只是为了扩展@ibrahim-mahrir 的答案,他们的意思是这样的

function getPaths() 
    var dirPath = document.getElementById("mdir").innerHTML;
    var filePaths = [];
    fs.readdir(dirPath, function(err, dir) 
        for (var i = 0, l = dir.length; i < l; i++) 
            var filePath = dir[i];
            filePaths.push(dirPath + "/" + filePath);
        
        console.log(filePaths);
        console.log(filePaths.length);
    );

【讨论】:

以上是关于array.length 为零,但数组中有元素 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Javascript 使数组中的新元素在 array.push 之后出现在不同的索引中(不像预期的那样在 array.length 索引中)

JavaScript 数组 length 属性获取数组长度或设置数组元素的数目

C#中如何获取数组的最后一个元素?

将输入的元素添加到数组中正确的位置(JAVA)

javascript说array.length是未定义的,但不是数组

array.length-=1 与 array.pop()