为什么javascript中要慎用循环里面的i?
先贴上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
margin: 100px auto;
padding: 0;
width: 800px;
height: 400px;
border: 1px solid black;
}
ul {
margin: 0;
padding: 0;
/*为父元素添加此元素,避免li出现间隙 */
display: table;
}
li {
display: inline-block;
list-style: none;
padding: 0 10px;
height: 30px;
line-height: 30px;
}
.bg_o {
background-color: orange;
}
.bg_w {
background-color: #ccc;
}
.tab_list {
height: 30px;
background-color: #cccccc;
}
.box1 {
display: none;
height: 250px;
background-color: orange;
z-index: 0;
}
</style>
</head>
<body>
<div class="box">
<div class="tab_list">
<ul>
<li class="bg_o">商品介绍</li>
<li>规格与包装</li>
<li>售后保障</li>
<li>商品评价(1.1万+)</li>
</ul>
</div>
<div class="tab_com">
<div class="box1" style="display:block">1</div>
<div class="box1">2</div>
<div class="box1">3</div>
<div class="box1">4</div>
</div>
</div>
<script>
var lis = document.querySelector('.tab_list').querySelectorAll('li');
var boxs = document.getElementsByClassName('box1');
var ch=[];
var account=0;
//使被点击的标题块变色
for (var i = 0; i < lis.length; ++i) { //lis是个伪数组,不能使用int表示下标
lis[i].setAttribute('index', i);
lis[i].onclick = function () {
for (var j = 0; j < lis.length; ++j) {
lis[j].className = '';
boxs[j].style.display = 'none';
}
this.className = 'bg_o';
var index=this.getAttribute('index'); //只能使用this来获取属性?
boxs[index].style.display='block';
}
}
</script>
</body>
</html>
运行的结果是这样的:
点击上头第三个盒子导航就会出现相应的第三个盒子的内容。
- 最初版本:
代码里面的 boxs[index].style.display=‘block’;
原来形式为:boxs[i].style.display='block';
即我希望使用参数i直接表示当前的盒。但运行后你会发现。报错
51tab栏切换制作.html?_ijt=gu23k502019u2i5rvcdptn7pmp:91 Uncaught TypeError: Cannot read property ‘style’ of undefined
at HTMLLIElement.lis..onclick (51tab栏切换制作.html?_ijt=gu23k502019u2i5rvcdptn7pmp:91);
也就是说属性property无法被设定。
-原因分析:
分析的过程就不在这里赘述了。程序员都懂,解决只需一瞬间,找出原因要几年。
使用浏览器debug之后会发现,在每次浏览器装载完之后,i的 值就变成了4,也就是伪数组lis[]溢出的第一个元素。截图如下:
更深层次原因我想应该和javascript的语言属性有关。js是一门脚本语言,边解释边执行的,所以在点击之前,其实已经把所有的事件触发都写好了。我自己理解是吧for()里面的循环已经写死了。类似于写成这样:
所以只是如果你再调用 lis[i],等价于调用lis[4],这个object元素之前是不存在的,所以就会无法赋值。这时候我们只能回到body中寻找标记了。这也是为什么只能用index的原因。 - 另外
getAttribute得到的元素类型是String,也就是返回的index是string类型,不过在装入lis[]中发生了隐式转换,转成了number类型。js的隐式转换挺多的,感觉和python有点类似。