所以,我对JavaScript有点陌生,我创建了一个测试脚本,只是为了看看它是如何通过JS应用样式的,以防对文档中的div应用display none,这是测试代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="hide">Test DIV 1</div>
<div id="hide">Test DIV 2</div>
<div id="hide">Test DIV 3</div>
<p><input type="button" value="hide DIV" onclick="hideDiv()"></p>
<script>
function hideDiv(){
let test = document.querySelectorAll('div#hide')
for(let i in test){
test[i].style.display = 'none'
}
}
</script>
</body>
</html>
但是onclick返回的是:
Uncaught TypeError: Cannot set property 'display' of undefined
at hideDiv (test.html:18)
at HTMLInputElement.onclick (test.html:13)
这个效果很好:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="hide">Test DIV 1</div>
<div id="hide">Test DIV 2</div>
<div id="hide">Test DIV 3</div>
<p><input type="button" value="hide DIV" onclick="hideDiv()"></p>
<script>
function hideDiv(){
let test = document.querySelectorAll('div#hide')
for(let i=0;i<test.length;i++){
test[i].style.display = 'none'
}
}
</script>
</body>
</html>
那么两者之间的区别是什么:
for(let i in test){
test[i].style.display = 'none'
}
和
for(let i=0;i<test.length;i++){
test[i].style.display = 'none'
}
只需记录正在迭代的属性,就会非常明显:
function hideDiv() {
let test = document.querySelectorAll('div#hide')
for (let i in test) {
console.log(i);
test[i].style.display = 'none'
}
}
<div id="hide">Test DIV 1</div>
<div id="hide">Test DIV 2</div>
<div id="hide">Test DIV 3</div>
<p><input type="button" value="hide DIV" onclick="hideDiv()"></p>
for..in
迭代对象及其所有内部原型的所有可枚举属性。
NodeList在其原型上有许多可枚举属性:.entries
、.keys
、.forEach
等等。这些属性不是元素,而是方法,因此当test[i]
不引用元素时,test[i].style
将是undefined
。
相比之下,进行
for(let i=0;i<test.length;i++){
在NodeList的从0到length
的严格数值上迭代,test[i]
将引用一个元素。