【问题标题】:Why can't I access JS object properties?为什么我无法访问 JS 对象属性?
【发布时间】:2013-10-25 23:02:43
【问题描述】:

我有以下功能:

function getAggregateData(){
        var sums = new Object();


    $.getJSON("example.json.php", function(data) {
           //for each month
           c = 0;
            $.each(data, function(key, val, index) {
                  //for each store
                $.each(val, function(key2, val2, index2) { 
                      if(c == 0){
                         sums[key2] = val2; 
                      }
                      else{
                         sums[key2] += val2; 
                      }

                });
                c++
            });

    })
    return sums;
}

然后我这样称呼:

var totals = getAggregateData();

但是当我控制台日志时,我完全被难住了:

console.log(totals)

显示这样的对象:

    store1  500
    store2  900
    store3  750
    and so on and so forth...

但是当我使用console.log(totals['store1') 时,我会变得不确定。

我也试过console.log(totals.store1)

和console.log(totals[0].store1)

我遇到了某种类型的范围问题,或者我没有创建我认为的对象。

【问题讨论】:

  • 这些console.log() 调用在哪里运行?
  • 来自服务器的原始 JSON 看起来如何?
  • 你应该避免使用 Object.new,使用var sums = {}see javascript-good-parts/bad-parts。此外,您还缺少 c 变量前面的 var 关键字。
  • @quantas,紧随 var totals = getAggregateData();
  • 我在 Chrome 控制台中生成了以下内容:gist.github.com/olleicua/7163441 这正是我所期望的。这表明您的 AJAX 调用可能没有返回您的想法。

标签: javascript object scope


【解决方案1】:

看起来该函数将返回一个空对象,因为它没有等待 AJAX 调用完成。

如果您尝试在 $.getJSON 回调中的最后一行执行 console.log(totals.store1),您将可能得到结果。

您需要将任何需要来自“example.json.php”数据的代码放入一个回调中,该回调仅在 AJAX 调用返回后运行。

例如

function getAggregateData(){
    var sums = new Object();

    $.getJSON("example.json.php", function(data) {
       //for each month
       c = 0;
        $.each(data, function(key, val, index) {
              //for each store
            $.each(val, function(key2, val2, index2) { 
                  if(c == 0){
                     sums[key2] = val2; 
                  }
                  else{
                     sums[key2] += val2; 
                  }

            });
            c++
        });

        processAggregateData(sums);

    })
}

function processAggregateData(totals) {
    console.log(totals.store1);
}

getAggregateData();

【讨论】:

  • 这确实有效。我之前的问题是范围问题。但是范围问题在这里继续阻碍我。我需要这些可以从外部轻松检索的值。如果我将对象传递给 processAggregateData,那么当我需要将它输入到图表或其他地方时,如何访问说 totals.store1?
  • 您可以通过将其附加到窗口对象来将其保存到全局变量中,例如窗口总数
  • 这是一种好的做法吗?我总是听说全局 JS 变量非常糟糕...如果必须,我会这样做,但只是试图不断改进...范围是我最大的障碍。
  • 您可以创建一个对象,将这些函数作为方法,并将总计作为该对象的属性。
【解决方案2】:

给定:

{
    "1": {
        "store1": 2450,
        "store2": 1060,
        "store3": 310
    },
    "2": {
        "store1": 2460,
        "store2": 1760,
        "store3": 810
    }
};

如果您打算为每个商店添加结果,这应该可以工作。

/**
* This functions need to be called when we have the data
*/
function processSums(obj){
    console.log(obj);
}

function getAggregateData(){

    var sums = {};

    $.getJSON("example.json.php", function(data) {
            $.each(data, function() {
                $.each(this, function(key, val, index){                
                    sums[key] = sums[key] || 0;
                    sums[key] += val;               
                });
            });
            // 4910
            processSums(sums);
    });

    return sums;
}

getAggregateData();

【讨论】:

  • 我删除了它,因为它并没有真正解决时间的核心问题,但这里是
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-05
  • 2018-06-22
  • 2021-05-06
  • 1970-01-01
  • 2016-07-22
相关资源
最近更新 更多