对象中的循环动态键似乎无法将数组输出到输出中

时间:2017-01-20 04:21:36

标签: javascript arrays

我正在尝试遍历一个对象,在该对象中我有一个对象和数组的混合。

对象

var templateObject = {
    "addressbook": {
        "streetaddress": ["streetaddress1", "1"],
        "country": ["country", "2"]
    },
    "companyname": ["thecompanyname", "1"],
    "email": ["theemail", "1"]
};

循环对象,我们不会总是知道对象中的键的名称,所以我试图循环它们

for(var prop in templateObject)
{
    document.write(prop);
    if(templateObject.hasOwnProperty(prop))
    {
        for(var subItem in templateObject[prop])
        {
            var currentItem = templateObject[prop][subItem];
            document.write('<b>' + currentItem[0] + '</b><br/>');
            document.write(currentItem[1]);        
            document.write('<hr/>');
        }
    }  
}

目前正在返回: -

  

地址簿streetaddress1 1国家2公司名称1未定义   电子邮件t h 1 undefined

我似乎能够毫无问题地获取地址簿对象,但我似乎无法获取公司名称或电子邮件并将其打印到屏幕上。

我希望有人可以帮助我,因为我一直在努力解决这个问题

我还在这里准备了一个小提琴:https://jsfiddle.net/dimmers/97mqke0f/

提前致谢

3 个答案:

答案 0 :(得分:0)

在对象上尝试Object.keys函数,非常好。

执行Object.keys(templateObject)应该为您提供addressbookcompanynameemail

此外var in仅适用于对象。它不适用于公司名称或电子邮件,因为它们是数组。

这对我有用:

var templateObject = {
    "addressbook": {
        "streetaddress": ["streetaddress1", "1"],
        "country": ["country", "2"]
    },
    "companyname": ["thecompanyname", "1"],
    "email": ["theemail", "1"]
};


function writeIt(currentItem) {
    // currentItem should be array
    document.write('<b>' + currentItem[0] + '</b><br/>');
    document.write(currentItem[1]);
    document.write('<hr/>');
}

for (var prop in templateObject) {
    document.write(prop);
    if (Object.prototype.toString.call(templateObject[prop]) == '[object Object]') {
        for (var subItem in templateObject[prop]) {
            var currentItem = templateObject[prop][subItem];
            writeIt(currentItem);

        }
    } else if (Object.prototype.toString.call(templateObject[prop]) == '[object Array]') {
        writeIt(templateObject[prop]);
    }
}

更新小提琴: https://jsfiddle.net/97mqke0f/1/

答案 1 :(得分:0)

您可以创建一个函数来获取键,然后递归调用它作为对象的属性(即typeof value == 'object')。但是您可能不希望迭代Arrays的值,因此请首先使用 Array.isArray 进行检查。

e.g。

function showKeys(obj) {

  // Get the keys of object and show them
  var keys = Object.keys(obj);
  document.write('<br>' + keys.join(', '));

  // Check for values that are Objects, ignore Arrays, and call recursively
  keys.forEach(function(key) {
    var value = obj[key];
    if (typeof value == 'object' && !Array.isArray(value)) {
      showKeys(value);
    }
  });
}

var templateObject = {
    "addressbook": {
        "streetaddress": ["streetaddress1", "1"],
        "country": ["country", "2"]
    },
    "companyname": ["thecompanyname", "1"],
    "email": ["theemail", "1"]
};

showKeys(templateObject);

这将处理任何深度的嵌套,但不会处理数组中的对象,但是获取这些对象也很简单(在数组上循环但不打印它们的键)。

答案 2 :(得分:0)

之前我遇到过类似的问题,我写了一个函数来解决它。这是我的代码,它将遍历一个对象并输出所有可枚举的属性。

function joOutput(o, decodeUrl) {
  var txt, depth, sp, sub, isEmpty;
  if (typeof o !== "object")
    return "[Not an object]";
  isEmpty = function(e) {
    var i;
    for (i in e)
      return false;
    return true;
  };
  if (isEmpty(o))
    return "[Empty Object]";
  txt = "<b>NOTE:</b>n for attribute name, d for depth, v for value.<br>";
  txt += "-----------------------------------<br>";
  depth = 0;

  sp = function(n) {
    var s = "";
    for (var i = 0; i < n; i++) {
      s += "&nbsp&nbsp&nbsp&nbsp&nbsp.";
    }
    return s;
  };
  sub = function(obj) {
    var attr;
    for (attr in obj) {
      if ((typeof obj[attr]) !== "object") {
        if (decodeUrl)
          obj[attr] = decodeURIComponent(obj[attr]);
        txt += sp(depth) + "[n: " + attr + " - d: " + depth + " - v: <b>" + obj[attr] + "</b>]<br>";
      } else {
        txt += sp(depth) + "[n:" + attr + " - d:" + depth + "]...<br>";
        depth++;
        arguments.callee(obj[attr]);
      }
    }
    depth--;
    return txt;
  };
  return sub(o);
}

// Test:
var templateObject = {
    "addressbook": {
        "streetaddress": ["streetaddress1", "1"],
        "country": ["country", "2"]
    },
    "companyname": ["thecompanyname", "1"],
    "email": ["theemail", "1"]
};

var txt = joOutput(templateObject);
document.write(txt);