【问题标题】:Returned array prints array index instead of value返回的数组打印数组索引而不是值
【发布时间】:2021-05-23 03:04:12
【问题描述】:

我有一个 FileHelper 方法,它列出了所有文件的名称并最终返回文件名:

import fs from 'fs';
import path from 'path';

class FileHelper {

    static ListFiles() {
        const fileDir = `${path.resolve()}/Specifications/`;
        let files = fs.readdirSync(fileDir);

        for (const file in files) {
            console.log(file); // Prints filename correctly: 'petstore.json'
        }

        return files;
    }

}

export default FileHelper;

但是,当我调用此方法并在 for 循环中再次打印它时,它会打印数组索引而不是值:

import FileHelper from './Helpers/FileHelper.js';

 function main() {  
  try {
    let specifications = FileHelper.ListFiles();

    for (const specification in specifications) {   
      console.log(specification); // prints '0' instead of 'petstore.json'
    }
  }
  catch(err) {
    console.error(err);
  }
}


main();

为什么在第二个 for 循环中不打印文件名?谢谢!

【问题讨论】:

  • for..in 仅迭代键。所以第二段代码是正确的。我不确定为什么第一个会给你名字,fs.readdirSync() 无论如何都会返回一个数组,所以遍历数组的键会给你索引。
  • @ArunKumarMohan 虽然这个问题是相关的,但这里的问题是为什么在同一个数组上使用 for..in 两次会产生完全不同的结果。
  • @VLAZ 是的,你是对的。但我无法重现该问题。

标签: javascript node.js arrays for-loop


【解决方案1】:

避免使用for...in 来迭代数组。而是使用for...of

例子

for (const specification of specifications) {
  console.log(specification);
}

【讨论】:

  • 感谢您的提示!我应该使用 for...of 而不是 for...in
【解决方案2】:

您看到键的原因是for...in 循环遍历数组的键。

 function main() {  
  try {
    let specifications = FileHelper.ListFiles();

    for (const key in specifications) {
      
      const { [key]: value }= specifications;
      // ^ the above line is equivalent to
      //   const value = specifications[key]
      
      console.log(key, value);
    }
  }

  catch(err) {
    console.error(err);
  }
}

查看MDN documentation on for...in,其中说明:

for...in 语句遍历对象的所有以字符串为键的可枚举属性(忽略以符号为键的那些),包括继承的可枚举属性。

在您的问题的 cmets 中,Arun 链接到一个出色的 StackOverflow 问题,该问题解释了实现目标的不同方法:why is using for...in for array iteration a bad idea

其中一种替代方式是for...of,它看起来:

for (const specification of specifications) {
  console.log(specification);
}

for...of 语句创建一个循环遍历可迭代对象,包括:内置字符串、数组、类数组对象(例如,参数或 NodeList)、TypedArray、Map、Set 和用户定义的可迭代对象.它调用一个自定义迭代钩子,其中包含要为对象的每个不同属性的值执行的语句。

此外,您可以使用Array.prototype.forEach() 遍历数组。这是这种方法:

specifications
  .forEach((currentKey) => {
    const { [currentKey]: specificationValue } = specifications;
    console.log(currentKey, specificationValue);
  })

或者你可以用老式的方式来做——使用for循环:

for (let i = 0; i < specifications.length; i++) {
  console.log(i, specifications[i])
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 2019-11-21
    相关资源
    最近更新 更多