差别一:隐藏元素是否返回
textContent 和 innerText 的核心差别在于:前者返回的是"原始文本内容",后者返回的是"渲染后可见的文本"。
html
<!DOCTYPE html>
<html>
<body>
<div id="demo">
第一行
<span style="display:none">隐藏内容</span>
<span style="visibility:hidden">不可见</span>
第二行
</div>
<script>
const el = document.getElementById('demo');
console.log(el.textContent);
// 输出(保留换行和缩进):
// "\n 第一行\n 隐藏内容\n 不可见\n 第二行\n"
console.log(el.innerText);
// 输出(只保留可见文本,并规范化空白):
// " 第一行 第二行"
</script>
</body>
</html>

差别二:是否对空白进行规范化处理
innerText 会对空白进行规范化(多个空格/换行合并为一个空格),textContent 则原样保留。
差别三:执行效率
innerText 的返回值依赖于元素的渲染状态。为了知道哪些内容"可见"、空白该如何规范化,浏览器可能需要重新计算布局(reflow),所以它读取效率较低,不适合在循环或高频操作中使用。
textContent 只是拼接 DOM 树里的文本节点,不关心 CSS,读起来快得多。
差别四:对元素内部定义的CSS样式结点与脚本结点的处理不同
textContent 会把元素内部定义的 <script> 和 <style> 里的文本也读出来,innerText 不会。
html
<!DOCTYPE html>
<html>
<body>
<div id="demo">
可见文字
<script>console.log('hi')</script>
<style>.a{color:red}</style>
</div>
<script>
const el = document.getElementById('demo');
console.log(el.textContent);
// 输出(保留换行和缩进):
// "\n 可见文字\n console.log('hi')\n .a{color:red}\n"
console.log(el.innerText);
// 输出(只保留可见文本,并规范化空白):
// " 可见文字"
</script>
</body>
</html>

差别五:写入行为不同
javascript
el.textContent = 'a\nb'; // 换行会被当作纯文本,显示为 "a b"(HTML 里换行不生效)
el.innerText = 'a\nb'; // 换行会被转换成 <br>,真正显示为两行
小结
| 维度 | textContent |
innerText |
|---|---|---|
| 定义来源 | DOM 标准 | HTML 标准(更偏渲染) |
| 隐藏元素内容 | 包含 | 不包含 |
| 空白处理 | 原样保留 | 规范化(类似浏览器显示效果) |
<br> 换行 |
不体现 | 体现为换行 |
| 性能 | 快(不触发重排) | 慢(可能触发重排/回流) |
对 script/style |
返回其文本 | 不返回 |