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

使用纯JavaScript转换嵌套JSON为HTML表格时出现未知数字问题求助

问题:嵌套JSON转HTML表格时出现莫名数字序号

我尝试通过公开API返回的嵌套JSON数据生成HTML表格,但表格顶部莫名出现0、1、2、3……这类数字,确认API返回结果里并没有这些数字。请问我忽略了什么?

以下是可运行代码:

<!DOCTYPE html>
<html>

<head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>

<body>
    <h2>Dynamic HTML Table from Any Nested JSON API's response.</h2>
    <button id="foo">Build table</button>
    <table class="table table-sm table-bordered">
        <tbody id="output">
        </tbody>
    </table>
</body>

<script>
    const button = document.querySelector('#foo');
    button.addEventListener('click', fetchData, false);
    function fetchData() {
        button.textContent = 'Loading...';
        button.disabled = true;
        const outputElement = document.getElementById("output");
        setTimeout(() => {
            fetch('https://jsonplaceholder.typicode.com/users')
                .then(response => response.json())
                .then(data => {
                    renderNestedJSON(data, outputElement);
                })
                .catch(error => console.error(error));
        }, 500);

    }
    function renderNestedJSON(data, parentElement) {
        for (const key in data) {
            if (typeof data[key] === "object") {
                // If an object - Recursive
                const nestedWhips = document.createElement("td");
                nestedWhips.className = "className";
                parentElement.appendChild(nestedWhips);

                const keyElement = document.createElement("td");
                keyElement.textContent = key + ": ";
                nestedWhips.appendChild(keyElement);

                renderNestedJSON(data[key], nestedWhips);
            } else {
                // Else render it as-is 
                const keyValueElement = document.createElement("tr");
                keyValueElement.textContent = `${key} : ${data[key]}`;
                parentElement.appendChild(keyValueElement);
            }
        }
        button.remove();
    }
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
    crossorigin="anonymous"></script>
</html>

问题原因

出现这些数字的核心原因是API返回的是数组而非单个对象,你的renderNestedJSON函数直接用for...in遍历了数组的索引键。

当你调用renderNestedJSON(data, outputElement)时,data是包含10个用户对象的数组,for...in遍历数组时,会把数组的索引(0、1、2...)当作键来处理。因为数组属于object类型,所以进入了递归分支,把索引(0、1等)作为key渲染了出来。

修复方案

调整函数逻辑,优先区分数组和普通对象的处理方式:

<!DOCTYPE html>
<html>

<head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>

<body>
    <h2>Dynamic HTML Table from Any Nested JSON API's response.</h2>
    <button id="foo">Build table</button>
    <table class="table table-sm table-bordered">
        <tbody id="output">
        </tbody>
    </table>
</body>

<script>
    const button = document.querySelector('#foo');
    button.addEventListener('click', fetchData, false);
    function fetchData() {
        button.textContent = 'Loading...';
        button.disabled = true;
        const outputElement = document.getElementById("output");
        setTimeout(() => {
            fetch('https://jsonplaceholder.typicode.com/users')
                .then(response => response.json())
                .then(data => {
                    renderNestedJSON(data, outputElement);
                })
                .catch(error => console.error(error));
        }, 500);

    }
    function renderNestedJSON(data, parentElement) {
        // 优先处理数组:遍历每个元素,创建独立行
        if (Array.isArray(data)) {
            data.forEach(item => {
                const row = document.createElement('tr');
                parentElement.appendChild(row);
                renderNestedJSON(item, row);
            });
            return;
        }

        // 处理普通对象
        for (const key in data) {
            // 排除null(null的typeof也是object)
            if (typeof data[key] === "object" && data[key] !== null) {
                const cell = document.createElement("td");
                // 显示键名
                const keyLabel = document.createElement("span");
                keyLabel.textContent = `${key}: `;
                cell.appendChild(keyLabel);
                parentElement.appendChild(cell);
                // 递归渲染嵌套内容
                renderNestedJSON(data[key], cell);
            } else {
                // 普通键值对,创建单元格展示
                const cell = document.createElement("td");
                cell.textContent = `${key}: ${data[key]}`;
                parentElement.appendChild(cell);
            }
        }
        button.remove();
    }
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
    crossorigin="anonymous"></script>
</html>

修复说明

  • 新增Array.isArray(data)判断,优先处理数组类型,避免遍历数组索引
  • 为每个数组元素(用户对象)创建独立的<tr>行,保证表格结构正确
  • 修复嵌套对象的渲染逻辑,确保键和值在同一个单元格内展示,符合表格规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 23:20:15