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

Leo*_*eon 0 javascript

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

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

{
    title: 'Foo',
    content: {
        top: 'Bar',
        bottom: 'Baz'
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

for (var property in object) {
    if (object.hasOwnProperty(property)) {
        // do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

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

lea*_*eaf 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]";
}
Run Code Online (Sandbox Code Playgroud)

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

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]";
}
Run Code Online (Sandbox Code Playgroud)