0

So, i'm kinda new into JavaScript and i was creating a test script just to see how it works to apply style through JS, in case applying display none to the divs in the document, this is the test code:

<!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>

But the onclick returns this:

Uncaught TypeError: Cannot set property 'display' of undefined
at hideDiv (test.html:18)
at HTMLInputElement.onclick (test.html:13)

And this one works well:

<!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>

So what is the difference beetween:

for(let i in test){
    test[i].style.display = 'none'
}

And

for(let i=0;i<test.length;i++){
    test[i].style.display = 'none'
}

1 Answers1

3

Just log the property being iterated over, and it'll be pretty obvious:

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 iterates over all enumerable properties on the object and on all of its internal prototypes.

A NodeList has many enumerable properties on its prototype: .entries, .keys, .forEach, and more. These properties are not elements, but methods, so when test[i] doesn't refer to an element, test[i].style will be undefined.

In contrast, doing

for(let i=0;i<test.length;i++){

iterates over strictly numerical values from 0 to the length of the NodeList, and test[i] will refer to an element.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320