for(let value of values){ ul.innerHTML += '<li>${value}</li>';}<p>这段代码效率低,因为每次迭代都要设置一次innerHTML,不仅如此,每次循环都要先读取innerHTML,也就是说一次循环要访问两次innerHTML。
let itemsHtml = "";for(let value of values){ itemsHtml += '<li>${value}</li>';}ul.innerHTML = itemsHtml;<p>这样修改之后,效率就高多了,只会对innerHTML进行一次赋值,下面代码也可以搞定:
ul.innerHTML = values.map(value => '<li>${value}</li>').join(' ');
<ul id="myGirls"> <li id="girl1">比比东</li> <li id="girl2">云韵</li> <li id="girl3">美杜莎</li></ul><p>这里包含三个列表项,在被点击时应该执行某个操作,通常的方式是指定三个事件处理程序:
let item1 = document.getElementById("girl1");let item2 = document.getElementById("girl2");let item3 = document.getElementById("girl3");item1.addEventListener("click",(event) => { console.log("我是比比东!");})item2.addEventListener("click",(event) => { console.log("我是云韵!");})item3.addEventListener("click",(event) => { console.log("我是美杜莎!");})<p>相同代码太多,代码过于丑陋了。
let list = document.getElementById("myGirls");list.addEventListener("click",(event) => { let target = event.target; switch(target.id){ case "girl1": console.log("我是比比东!"); break; case "girl2": console.log("我是云韵!"); break; case "girl3": console.log("我是美杜莎!"); break; }})
btn.onclick = null;//删除事件处理程序
,事件委托也有助于解决这个问题,如果得知某个元素要被innerHTML替代的时候,就不要给该元素添加事件处理程序了,将其添加到更高层级的节点上即可。
let ps = document.getElementsByTagName("p");for(let i = 0;i<ps.length;++i){ let p = document.createElement("p"); document.body.appendChild(p);}
let ps = document.getElementsByTagName("p");for(let i = 0,len=ps.length;i<len;++i){ let p = document.createElement("p"); document.body.appendChild(p);}<p>表达式①中第一行取得了包含文档中所有
<p>元素的HTMLCollection。因为这个集合是实时的,所以任何时候只要向页面中添加一个新的<code><p>
元素,再查询这个集合就会多一项。因为浏览器不希望保存每次创建的集合,所以就会在每次访问时更新集合。每次循环都会求值i < ps.length
,这意味着要获取所有<p>
元素的查询。因为循环体中创建并向文档中添加一个新的<p>
元素,所以每次循环ps.length的值也会递增。因为两个值都会递增,所以i永远不会等于ps.length
,因此表达式①会造成死循环。for循环中初始化变量处只会初始化一次
),所以就可以避免表达式①中出现的无穷循环问题。let ps = document.getElementsByTagName("p");for(let i = ps.length-1;i>=0;--i){ let p = document.createElement("p"); document.body.appendChild(p);}
以上是深入了解JavaScript的内存与性能问题的详细内容。更多信息请关注PHP中文网其他相关文章!