Circular events (forEach, for..in, and for..of)

Posted by Keith Scott on Wed, 20 Oct 2021 05:35:16 +0200

Circular events (forEach, for... in, and for... of)

Once, I suddenly found that in forEach, if you use return, you can't exit the whole loop or get the return value, but it seems that you can jump out of the current loop.

var arr = [1,1,2,1,1]
function test(){
        arr.forEach((item)=>{
        	if(item==2)return item;
        	console.log("this is",item)
    	})
}
    //test()
console.log(test())//output:undefined

According to MDN

There is no way to abort or jump out of a forEach() loop except by throwing an exception. If you need to abort or jump out of a loop, the forEach() method is not the tool you should use.

function test(){
        try{
            arr.forEach((item)=>{
                if(item==2)throw new Error("Error");//Throw an error and terminate the loop
                console.log("this is",item)
            })
        }catch(error){
            alert(error)
        }
 }
    //test()
console.log(test())

Fatal Frame

This also reminds me of the other two loop methods - > for... in and for... Of

one

For... in is mainly used to traverse object properties. Therefore, if you need to traverse the values of arrays, for... in is not an appropriate choice.

var arr = [1,1,2,1,1]
for(let item in arr){
            //if(item==2)return item;
    console.log("this is",item)
}  

output: 
this is 0
this is 1
this is 2 
this is 3
this is 4//This is traversing the index of the array

When we add new attributes to it

var arr = [1,1,2,1,1];
var reducer = (accumulator,currentValue)=>accumulator+currentValue;

//Add attribute form 1 👇
Object.defineProperty(arr,"sum",{
   value:arr.reduce(reducer)
})
//Add attribute form 2 👇
arr.test = "first"
//Add attribute form 3 👇
Array.prototype.rank = "second"

console.log(Object.propertyIsEnumerable("sum"),Object.propertyIsEnumerable("first"),Object.propertyIsEnumerable("second"))

//console.log(arr)
for(let item in arr){
    console.log("this is",item)
 }   

output:
false true false
this is 0
this is 1
this is 2 
this is 3
this is 4
this is rank
this is test

Here are a few points to note:

1.for... in can only traverse enumerable attributes

2. The method of adding attribute 1 allows you to accurately add or modify object attributes. The defined enumerable value is false by default. When the value is modified to true, it can be displayed when traversing object attributes.

3. The method of adding attribute 2 is to directly assign attributes, which can be enumerated in general

4. The method of adding attribute 3 is to directly add attributes on the object prototype. The attributes inherited through the prototype chain can be traversed in for... In

Object.propertyIsEnumerable() can determine whether the specified property in the object can be for...in Circular enumeration, except for properties inherited through the prototype chain. If the object does not have the specified property, this method returns false.

Therefore, when judging whether it is enumerable or not, the rank attribute is not recognized by the above method and returns a false value

two

As for... Of, obviously, it is different from for... In in in that it can be used to purely traverse the values of an array. But in addition, it can also be used to traverse class arrays. nodelist, HTMLCollection, arguments, etc. can be regarded as class arrays. Although they have the length attribute of the array and can be traversed, they do not have other methods of array. This means that it is not advisable to use forEach traversal. We can consider using direct for loop or for... Of to solve the problem of class array traversal.

<button class="wu">kanwo</button>
<button class="wu">kanwo</button>
<button class="you">kanwo</button>
<button class="wu">kanwo</button>
var col = document.getElementsByClassName("wu");
for(let item of col){
    console.log("this is",item)
}
var col = document.getElementsByClassName("wu");
for(let item of col){
    console.log("this is",item)
}

Topics: Javascript