两个递归函数之间的区别

Difference between two recursive functions

本文关键字:之间 区别 递归函数 两个      更新时间:2023-09-26

findElementById

function findElementRecursion (inputId, currentElement) {
    if (currentElement.id == inputId) {
        return true;
    }
    var numChildren = currentElement.children.length;
    if (numChildren > 0) {
        for (i=0; i<numChildren; i++) {
            var currentChild = currentElement.children[i];
            console.log(currentChild);
            return findElementRecursion(inputId, currentChild);
        }
    }   
    return false;
}

有人能帮我调试这个递归函数吗?当它应该返回true时,它返回false。由于我没有看到任何错误消息,我很难弄清楚问题出在哪里。如果有人告诉我调试这类问题的步骤会很有帮助。

更新:问题是,我只是在检查了currentElement的第一个孩子之后才返回。我修复了这个问题,但函数在应该返回true时仍然返回false。

function findElementRecursion (inputId, currentElement) {
    if (currentElement.id == inputId) {
        return true;
    }
    var numChildren = currentElement.children.length;
    if (numChildren > 0) {
        for (i=0; i<numChildren; i++) {
            var currentChild = currentElement.children[i];
            if (findElementRecursion(inputId, currentChild)) {
                return true;
            }
        }
    }   
    return false;
}

findElementRecursion (主栏, document)的控制台上尝试此操作,您将看到false

function findElementRecursion (inputId, currentElement) {
    var result = false;
    if (currentElement.id == inputId) {
        return true;
    }
    for (var i=0; i<currentElement.children.length; i++) {
        var currentChild = currentElement.children[i];
        console.log(currentChild);
        result = findElementRecursion(inputId, currentChild);
        // we can break here
        if(result)
             return true;
    }
    return false;
}

如果我要这样做,我不会使用递归函数,我只会使用getElementsByTagName。它会更快,并以相同的顺序遍历元素。它也将只访问元素,而其他方法也可能访问文本节点。

function findElementById(id, root) {
  root = root || document;
  var elements = root.getElementsByTagName('*');
  for (var i=0, iLen=elements.length; i<iLen; i++) {
    if (elements[i].id == id) {
      return elements[i];
    }
  }
}

但也许你只是想要一个递归函数作为练习。

function findElementByIdRecursive(id, element) {
  // If no element passed in, use document
  element = element || document;
  // If element has id, return it
  if (element.id == id) return element;
  // Otherwise, keep going
  var foundElement;
  var childNodes = element.childNodes;
  // Not needed on modern browsers but older browsers may throw an error
  // if the node can't have children (like a text node)
  if (childNodes) {
    // Only keep looping while a matching element isn't found    
    for (var i=0,iLen=childNodes.length; i<iLen  && !foundElement; i++) {
      // Save a call if this node matches    
      if (childNodes[i].id == id) {
        return childNodes[i];
      }
      // Otherwise, go down its children
      foundElement = findElementByIdRecursive(id, childNodes[i]);
    }
    return foundElement;
  }
}

可能有更好的方法可以做到这一点,比如使用jQuery,但这应该有效:

function findElementRecursion (inputId, currentElement) {
  if (currentElement.id == inputId) {
    return true;
  }
  if (!currentElement.children) return false;
  var numChildren = currentElement.children.length;
  if (numChildren > 0) {
    for (var i in currentElement.children) {
      var currentChild = currentElement.children[i];
      console.log(currentChild);
      if (findElementRecursion(inputId, currentChild)) return true;
    }
  }   
return false;
}

注意,您还必须检查元素是否真的有子元素

您很早就打破了循环:

    function findElementRecursion (inputId, currentElement) {
        var result = false;
        if (currentElement.id == inputId) {
            return true;
        }
        var numChildren = currentElement.children.length;
        if (numChildren > 0) {
            for (i=0; i<numChildren; i++) {
                var currentChild = currentElement.children[i];
                console.log(currentChild);
                result = findElementRecursion(inputId, currentChild);
                if(result){
                   break;
                   }
            }
        }   
        return result;
    }

从初始代码开始,

function findElementRecursion (inputId, currentElement) {
    if (currentElement.id == inputId) {
        return true;
    }
    var numChildren = currentElement.children.length;
    if (numChildren > 0) {
        for (i=0; i<numChildren; i++) {
            var currentChild = currentElement.children[i];
            console.log(currentChild);
            return findElementRecursion(inputId, currentChild);
        }
    }   
    return false;
}

问题是我返回得太早,只检查了每个currentElement的第一个元素就脱离了循环。

function findElementRecursion (inputId, currentElement) {
    if (currentElement.id == inputId) {
        return true;
    }
    var numChildren = currentElement.children.length;
    if (numChildren > 0) {
        for (i=0; i<numChildren; i++) {
            var currentChild = currentElement.children[i];
            console.log(currentChild);
            if (findElementRecursion(inputId, currentChild)) return true;
        }
    }   
    return false;
}

但是,当函数应该返回true时,它仍然返回false。这是因为我没有将i设置为局部变量。它应该是var i,所以它包含在每个本地环境中。

function findElementRecursion (inputId, currentElement) {
    if (currentElement.id == inputId) {
        return true;
    }
    var numChildren = currentElement.children.length;
    if (numChildren > 0) {
        for (var i=0; i<numChildren; i++) {
            var currentChild = currentElement.children[i];
            console.log(currentChild);
            if (findElementRecursion(inputId, currentChild)) return true;
        }
    }   
    return false;
}

一切都很好!