javascript:array.length计算为未定义

时间:2019-03-25 18:08:21

标签: javascript arrays

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

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

有什么想法吗?谢谢!

一些受访者要求提供更多代码。这里是更多上下文:

从Promise函数中调用getInsights方法,这是异步$ http.get的结果。因此,是的,数据的来源是异步的,但是在将数据传递给此方法之前,数据已完全解析。 (除非我完全误解了promise构造的机制。可能的是-这种环境对我来说是非常新的。)

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));

就在循环之前。这就是产生的结果-

{“位置”:[{“名称”:“帐户/ 1060596 ###### 92928 / locations / 1520987 ###### 801267”,“ locationName”:“ Lawrence Primus MD”,“ primaryPhone “:”(123)456-7890“,” primaryCategory“:...

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

2 个答案:

答案 0 :(得分:3)

如果仔细查看调试器(在上一个屏幕截图中),您会发现location不是数组,它实际上是带有键locations的对象,该键是数组。这就是为什么location.length未定义的原因。

这是变量位置中的数据

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

所以您要做的就是...

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

它应该可以工作。

或者,您可以在调用该函数时直接传入locations数组。

angularScope.getInsights(response.data.locations);

可能更干净

答案 1 :(得分:2)

在这种情况下,可以帮助明确地将对象字符串化并将其输出到控制台。如您所言,输出:

  

{“位置”:[{“名称”:“帐户/ 1060596 ###### 92928 / locations / 1520987 ###### 801267”,“ locationName”:“ Lawrence Primus MD”,“ primaryPhone “:”(123)456-7890“,” primaryCategory“:...

因此很显然Error in `[.default`(df, , "Republican", drop = FALSE) : subscript out of bounds Calls: <Anonymous> ... colSums -> -> is.data.frame -> [ -> [.table -> NextMethod In addition: Warning messages: 1: package 'tidyverse' was built under R version 3.5.2 2: package 'tidyr' was built under R version 3.5.2 3: package 'forcats' was built under R version 3.5.2 Execution Halted 不是数组,而属性locations是数组。在控制台中很难发现这一点,尽管一旦您知道了它,那也很明显。

要解决此问题,只需更改locations变量以表示该内部数组:

locations