javascript:array.length的计算结果为undefined

问题描述 投票:0回答:2

简单的代码块,循环遍历数组:

for (var i = 0; i < locations.length; i++) {
    jsonPost.locationNames.push(locations[i].name);
}

请看截图 - 这对我来说就像一个合法的数组,调试器显示6个条目,长度为6。

debug snapshot 1

但是,locations.length的计算结果为undefined。 (请参阅第二个屏幕截图。)我甚至使用调试器中的“复制属性路径”功能来确保我的代码没有输入错误但仍然没有快乐 - 在调试窗口中的locations.length = 6但它的评估为在我的代码中未定义。

debug snapshot 2

有任何想法吗?谢谢!

一些受访者要求提供更多代码。这里有更多背景:

方法getInsights是在promise函数中调用的,它是异步$ http.get的结果。所以,是的,数据的来源是异步的,但数据在传递给此方法时已完全解析。 (除非我完全误解了承诺构造的机制。哪种可能 - 这对我来说是个新环境。)

try {
      debugAlert("getLocations:Will fetch Locations");
      $http.get("https://mybusiness.googleapis.com/v4/" + acct.name + "/locations" + angularScope.accessToken()).
          then(function (response, acct) {
              angularScope.viewLocations(response.data);
              angularScope.getInsights(response.data);
         });
 }

(我怀疑你需要这个$ http.get / promise编码的方法的完整代码,我最初不包括这个,因为我不想混淆水域。如果你觉得你需要它,请告诉我。)

这是完整的getInsights方法。 (同样,在我们进入json数组处理之前,这一切都相当简单。)

$scope.getInsights = function (locations) {

    debugAlert("getInsights:Enter");

    if (!userSignedIn) {
        debugAlert("getInsights:Bail");
        insights = null;
        return;
    }

    debugAlert("getInsights:Initialize insights");
    $scope.insights = "Insights are being initialized...";

    try {
         debugAlert("getInsights:Will fetch Insights");

         var url = "https://mybusiness.googleapis.com/v4/" + $scope.selectedAcct.name + "/locations:reportInsights" + angularScope.accessToken();

         var jsonPost = {
             "locationNames": [],
             "basicRequest": {
                 "metricrequests": [],
                 "timerange": {
                     "startTime": "",
                     "endTime" : ""
                 }
             }
         };

         for (var i = 0; i < locations.length; i++) {
             jsonPost.locationNames.push(locations[i].name);
         }
         $http.post(url, jsonPost).
            then(function (response) {
                angularScope.viewInsights(response.data);
            });
    }
    catch (err) {
        alert("getInsights:Error!");
        alert("getInsights:" + err);
    }
     debugAlert("getInsights:Ready to Exit");
     return function () {
        return fn.apply();
     }
 };

这行代码永远不会执行 -

   jsonPost.locationNames.push(locations[i].name);

因为表达的locations.length计算为undefined,这完全是神秘的,因为调试器非常清楚地表明这个属性存在,并且它在中断时的值(第一个断点 - 第二个断点从不命中)是6。

location.length evaluates to 6 within debugger

请看屏幕截图。我很乐意提供尽可能多的代码。同时,查看调试信息会增加上下文并增加我要问的问题。谢谢!

我在声明中提出了这个问题

的console.log(JSON.stringify(位置));

就在循环之前。这是收益率 -

{“locations”:[{“name”:“accounts / 1060596 ###### 92928 / locations / 1520987 ###### 801267”,“locationName”:“Lawrence Primus MD”,“primaryPhone”:“ (123)456-7890“,”primaryCategory“:...

这是问题吗?位置实际上不是数组,而是包含数组的对象吗?如果是这样,我该如何引用数组?谢谢!

javascript arrays
2个回答
2
投票

在这种情况下,它可以帮助显式字符串化对象并将其输出到控制台。正如您所评论的那样,产出:

{“locations”:[{“name”:“accounts / 1060596 ###### 92928 / locations / 1520987 ###### 801267”,“locationName”:“Lawrence Primus MD”,“primaryPhone”:“ (123)456-7890“,”primaryCategory“:...

因此很明显,locations不是数组,但属性locations是。这在控制台中很难被发现,虽然一旦你知道它,它也会变得很明显。

所以要修复,只需更改locations变量来表示内部数组:

locations = locations.locations;

3
投票

如果仔细查看调试器(在上一个屏幕截图中),您将看到位置不是数组,它实际上是一个带有密钥locations的对象,它是一个数组。这就是为什么locations.length未定义。

这是变量位置中的数据

{
  locations: [
    { name: '...' },
    { name: '...' },
    { name: '...' },
    { name: '...' },
  ]
}

所以你需要做的就是......

for (var i = 0; i < locations.locations.length; i++) {

它应该工作。

或者,您可以在调用函数时传入位置数组。

angularScope.getInsights(response.data.locations);

这可能更干净了

© www.soinside.com 2019 - 2024. All rights reserved.