code: function depthFirstSearch(obj, handler) {
    var childrenKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
    var reverse = arguments[3];
  
    var rootChildren = hp.isArray(obj) ? obj : [obj];
    //
    var StopException = function StopException() {};
    var func = function func(children, parent) {
      if (reverse) {
        children = children.slice();
        children.reverse();
      }
      var len = children.length;
      for (var i = 0; i < len; i++) {
        var item = children[i];
        var r = handler(item, i, parent);
        if (r === false) {
          // stop
          throw new StopException();
        } else if (r === 'skip children') {
          continue;
        } else if (r === 'skip siblings') {
          break;
        }
        if (item[childrenKey] != null) {
          func(item[childrenKey], item);
        }
      }
    };
    try {
      func(rootChildren);
    } catch (e) {
      if (e instanceof StopException) {
        // stop
      } else {
        throw e;
      }
    }
  }
docs: 深度优先遍历 Depth-First-Search