为什么将document.getElementById获取的innerHTML赋值给变量后循环不生效?
两种DOM操作写法的差异及示例2不更新页面的原因
核心原理:基础值类型与引用类型的赋值差异
JavaScript中变量赋值分两种情况,这是两个示例效果不同的根本原因:
- 引用类型赋值:传递的是内存地址指针,修改变量会直接影响指向的原对象
- 基础值类型赋值:传递的是值的副本,修改变量不会影响原来的值
示例1运行逻辑
示例1中var output = document.getElementById('message');是将DOM元素对象的引用赋值给output变量,output直接指向页面中真实存在的#message节点。
每次循环中对output.innerHTML赋值时,都是直接修改该DOM节点的内置属性,浏览器会自动触发页面重渲染,所以内容会实时更新,符合预期。
var x = 0; var output = document.getElementById('message'); do { output.innerHTML = output.innerHTML + x; x = x + 1; } while (x < 6);
示例2运行逻辑
示例2中innerHTML是字符串类型,属于基础值类型,var output = document.getElementById('message').innerHTML;执行时,只会把当前#message节点的innerHTML文本值拷贝一份赋值给output变量。
后续所有output = output + x的操作都是修改这个独立的字符串副本,和原DOM节点没有任何关联。整个代码全程没有把修改后的字符串重新赋值给DOM节点的innerHTML属性,所以页面不会发生任何更新。
var x = 0; var output = document.getElementById('message').innerHTML; do { output = output + x; x = x + 1; } while (x < 6);
示例2修复方案
如果要让示例2达到和示例1相同的效果,只需要在循环结束后添加一行代码,把最终的output值写回DOM节点即可:
var x = 0; var output = document.getElementById('message').innerHTML; do { output = output + x; x = x + 1; } while (x < 6); // 新增赋值代码,把修改后的内容写回DOM document.getElementById('message').innerHTML = output;
补充说明:从性能角度看,修复后的示例2写法优于示例1。DOM操作的开销远高于普通变量运算,示例1每次循环都触发一次DOM更新,示例2只在最后做一次DOM更新,渲染效率更高。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

