【问题标题】:Adding a new field to my array of objects向我的对象数组添加一个新字段
【发布时间】:2017-06-01 18:16:48
【问题描述】:

我有一个很好的 hotdealArray 对象:

   [
        {
            "_id": "5908906b53075425aea0b16d",
            "property": "ATL-D406",
            "discount": 10,
            "hot": true
        },
        {
            "_id": "5908906b53075425aea0b16f",
            "property": "WAT-806",
            "discount": 20,
            "hot": true
        },
        {
            "_id": "5908906b53075425aea0b171",
            "property": "ANA-C202",
            "discount": 30,
            "hot": true
        }
    ]

我试试这个

hotdealArray[i].priceNight = result.res.priceNight;

这会给出错误:无法设置未定义的属性“priceNight”

如何向 hotdealArray 添加新字段?

这是我要求的 for 循环:

    for (var i=0; i<hotdealArray.length; i++) {
        var priceNight = 0;
        priceController.getPrice (
            { "body": { "propertyID": hotdealArray[i].property } }, 
            function(result) {
                if (result.error == true) {
                    throw new Error(result.err);
                } 
                priceNight = result.res.priceNight;
                console.log ("priceNight inside: " + priceNight);
            }
        );
        console.log ("priceNight outside: " + priceNight);
        hotdealArray[i].priceNight = priceNight;
    };

在控制台日志中,它只显示:

priceNight inside: 2160
priceNight inside: 2250
priceNight inside: 4455
priceNight inside: 1485

【问题讨论】:

  • 您需要提供更多上下文。 hotdealArray 不是您在参考时发布的数组,或者 i 不是 0、1 或 2。如果没有更多代码,我们将无法调试。
  • @ArnavAggarwal 如果您执行console.log(hotdealArray[i].property),那么您将获得一个值。它已经有值了,我只需要在每条记录中添加一个新的priceNightfield。
  • 请添加您用来循环数组的代码
  • 与大多数此类问题一样,最好提供minimal reproducible example,我们可以在其中查看运行中的代码并演示问题。正如@Lixus 所展示的那样,带有您提供的代码的 MCVE 并不能说明问题。
  • 哦,这是一个范围错误。这改变了一切。

标签: javascript arrays json


【解决方案1】:

还有其他方法,但避免范围问题的一种方法是将内部回调包装在 IIFE 中,该 IIFE 在该范围内显式定义 i

        function(result) {
            if (result.error == true) {
                throw new Error(result.err);
            } 
            console.log ("priceNight: " + result.res.priceNight);
            hotdealArray[i].priceNight = result.res.priceNight;
        }

变成

(function (i) {
  return function(result) {
    if (result.error == true) {
      throw new Error(result.err);
    } 
    console.log ("priceNight: " + result.res.priceNight);
    hotdealArray[i].priceNight = result.res.priceNight;
  };
})(i);

【讨论】:

  • 这可能会奏效。我只是不明白为什么我不能从结果函数内部访问任何范围变量。很奇怪。让我更新问题,以便您查看。
  • 为什么我无法访问 function(result) {} 中的任何内容 - 为什么在 priceController.getPrice () 之后我无法执行任何操作,它完全忽略了这些行
  • 因为它是一个回调函数,它对任何本地定义的变量都没有作用域,回调往往具有全局作用域。要么具有全局范围的变量,要么将它们设置为 IIFE 中的参数,类似于我对 i 所做的。
  • 我想我明白了 - 它实际上做的一切都是正确的,唯一的问题是 getPrice 没有设置为承诺,所以一旦整个循环完成,那就是 priceNight 开始返回的时候时间我们不再在代码/循环中。我需要将调用隔离为一个函数并做出承诺。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-25
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多