【问题标题】:Variable not visible inside for loop变量在 for 循环内不可见
【发布时间】:2019-02-02 17:58:32
【问题描述】:

我在 JavaScript 中有一个 for 循环,例如

var loopvariable = 0;  
let row = [[]];
for (var key in supplies.food) {
     row[loopvariable][0] = key;
     row[loopvariable][1] = supplies.food[key];
     loopvariable++;
}

为什么会出现以下错误

TypeError: row[loopvariable] 未定义

【问题讨论】:

  • 对于未来的问题,请提供一个 minimal reproducible example 来演示问题,最好是一个使用堆栈片段的可运行[<>] 工具栏按钮;here's how to do one)。您在对我的回答的评论中说 supplies.food 是一个数组。这很令人惊讶,因为for-in 不是循环遍历数组的正确方法。如果您提供完整的信息,就可以更好地为您提供帮助。

标签: javascript arrays scope


【解决方案1】:

变量

row[loopvariable]

未初始化。您可以使用默认值并使用保护运算符 (logical OR ||) 获取数组。

row[loopvariable] = row[loopvariable] || [];

更短的方法可能是将新数组推送到row,而不使用附加变量loopvariable

let row = [];
for (var key in supplies.food) {
    row.push([key, supplies.food[key]]);
}

【讨论】:

    【解决方案2】:

    TL;DR

    Object.entries 提供您尝试在那里创建的确切输出:

    let row = Object.entries(supplies.food);
    

    详细信息以及您的代码无法正常工作的原因

    您只在row[0] 创建了一个数组,而不是在row[1]row[2]row[3],...),但是您尝试在row[1] 上使用一个数组循环的第二次迭代。

    最小的变化是将内部数组的创建留给循环体:

    var loopvariable = 0;  
    let row = [];                                      // ***
    for (var key in supplies.food) {
         row[loopvariable] = [];                       // ***
         row[loopvariable][0] = key;
         row[loopvariable][1] = supplies.food[key];
         loopvariable++;
    }
    

    但我们也可以使用数组初始化器来更简洁:

    var loopvariable = 0;  
    let row = [];
    for (var key in supplies.food) {
         row[loopvariable++] = [
             key,
             supplies.food[key]
         ];
    }
    

    但是,同样,对于这种特定情况,您可以使用Object.entries

    let row = Object.entries(supplies.food);
    

    现场示例:

    const supplies = {
      food: {
        water: "3l",
        bread: "2 loaves",
        chocolate: "4 bars"
      }
    };
    let row = Object.entries(supplies.food);
    console.log(row);

    Object.entries 在所有现代环境中都受支持,并且可以在旧环境中轻松填充。

    您在评论中说supplies.food 是一个数组。如果是这样,for-in 不是循环遍历它的正确方法(有关详细信息,请参阅 this answer),但 Object.entries 仍然有效,因为数组也是对象(有关更多信息,请参阅 my blog post):

    const supplies = {
      food: [
        "3l water",
        "2 loaves bread",
        "4 bars chocolate"
      ]
    };
    let row = Object.entries(supplies.food);
    console.log(row);

    【讨论】:

    • @akshaykishore - 实际上,看看您正在生产的阵列,这正是您从 Object.entries 得到的,我已添加到答案的末尾。
    • 实际上这里的食物是一个数组而不是一个对象,所以我不知道这是否可行
    • @akshaykishore - 是的,它会(因为数组也是对象)。但是for-in 不是循环数组的正确方法。我已在答案末尾添加了详细信息。
    猜你喜欢
    • 2016-05-06
    • 1970-01-01
    • 2021-09-10
    • 2017-06-21
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多