You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

《Eloquent JavaScript》第14章递归函数异常返回问题求助

问题原因与解决方案

问题根源

你的script标签写在了</html>标签之后,浏览器会自动将这个脚本元素纳入document.body的子节点列表中。而脚本代码里明确包含字符串"book"(比如console.log(talksAbout(document.body, "book"));这一行),当递归函数遍历到script元素的文本子节点时,会检测到这个"book",因此函数返回true。

解决方案

方案1:调整脚本位置

将script标签移动到<head>标签内部,这样document.body的子节点就不会包含该脚本,函数只会遍历页面的可见内容:

<!doctype html>
<html>
  <head>
    <title>My home page</title>
    <script>
      function talksAbout(node, string) {
        if (node.nodeType == Node.ELEMENT_NODE) {
          for (let child of node.childNodes) { 
            if (talksAbout(child, string)) {
              return true;
            }
          }
          return false;
        } else if (node.nodeType == Node.TEXT_NODE) {
          return node.nodeValue.indexOf(string) > -1;
        }
      }

      // 页面加载完成后再执行,避免找不到document.body
      window.onload = function() {
        console.log(talksAbout(document.body, "book"));
      };
    </script>
  </head>
  <body>
    <h1>My home page</h1>
    <p>Hello, I am Marijn and this is my home page.</p>
    <p>I also wrote a !  Read it
      <a href="http://eloquentjavascript.net">here</a>.</p>
  </body>
</html>

方案2:修改函数跳过script标签

在递归函数中添加判断,遇到script元素时直接返回false,不遍历其内容:

function talksAbout(node, string) {
  if (node.nodeType == Node.ELEMENT_NODE) {
    // 跳过script标签,避免检测脚本内容
    if (node.tagName.toLowerCase() === 'script') return false;
    for (let child of node.childNodes) { 
      if (talksAbout(child, string)) {
        return true;
      }
    }
    return false;
  } else if (node.nodeType == Node.TEXT_NODE) {
    return node.nodeValue.indexOf(string) > -1;
  }
  // 处理其他未知节点类型,默认返回false
  return false;
}

额外优化

原函数缺少对非元素、非文本节点的返回值处理,虽然这不是当前问题的直接原因,但补充return false可以避免潜在的逻辑漏洞。

内容的提问来源于stack exchange,提问作者feinNotiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 22:42:08