如何循环对象键值和嵌套值

时间:2017-11-23 19:18:21

标签: javascript

我不认为“嵌套值”是正确的术语,但这是我正在尝试做的事情:

假设我有一个看起来像这样的对象:

{
    title: 'Foo',
    content: {
        top: 'Bar',
        bottom: 'Baz'
    }
}

我想检查标题或content.top或content.bottom是否包含某个字符串。

我发现我可以用这样的东西遍历对象键:

for (var property in object) {
    if (object.hasOwnProperty(property)) {
        // do stuff
    }
}

但是,如果键本身是一个对象并包含其他键,该怎么办?如果这些键也是具有不同键的对象怎么办?基本上,有没有办法以“深入”的方式搜索整个对象,这样无论值“嵌套”多深,它都会搜索所有值?

1 个答案:

答案 0 :(得分:5)

嵌套对象形成一个称为树的递归数据结构,并且树可以通过递归函数轻松浏览。递归函数是调用自身的函数,如下面的browse函数:

var tree = {
  a: "azerty",
  child: {
    q: "qwerty"
  }
};

browse(tree);

function browse (tree) {
  for (var k in tree) {
    if (isTree(tree[k])) {
      browse(tree[k]);
    } else {
      console.log(k, tree[k]);
    }
  }
}

function isTree (x) {
  return Object.prototype.toString.call(x) === "[object Object]";
}

但是,此功能旨在反复执行相同的任务。更通用的方法是外包应用于每个叶子的操作:

var tree = {
  a: 'azerty',
  child: {
    q: 'qwerty'
  }
};

browse(tree, log);
browse(tree, searchQ);

function browse (tree, operation) {
  for (var k in tree) {
    if (isTree(tree[k])) {
      browse(tree[k], operation);
    } else {
      operation(k, tree[k]);
    }
  }
}

function log (label, leaf) {
  console.log("logged", label, leaf);
}

function searchQ (label, leaf) {
  if (leaf.indexOf('q') !== -1) {
    console.log("found", label, leaf);
  }
}

function isTree (x) {
  return Object.prototype.toString.call(x) === "[object Object]";
}