Amrita Stha
Amrita Stha

Reputation: 3327

For in and Object.keys - es6

Shouldn't these two function return the same? For in is giving me ForInStatement is not allowed syntax restriction while Object.keys gives me totally different result. As soon as it return false, why is it looping again?

I want to check if any of the elements in an object is null or empty. As soon as it returns false, why is it still looping in Object.keys? While in ForIn, it return false and the loop stops as soon as the empty element is detected in an object.

For In

checkEmpty = (obj) => {
    for (const key in obj) {
      if (obj[key] === null || obj[key] === '') {
        console.log('forIn', obj[key] === null || obj[key] === '');
        return false;
      }
    }
    return true;
}

Object.keys

checkEmpty = (obj) => {
    Object.keys(obj).forEach(key => {
          if (obj[key] === null || obj[key] === '') {
            console.log('forEach', obj[key] === null || obj[key] === '');
            return false;
          }
    });
    return true;
}

Upvotes: 0

Views: 512

Answers (2)

Ori Drori
Ori Drori

Reputation: 191916

Array.forEach() return value is ignored, and you can't break the loop like you do in for...in. Your case you can use Array.some()to return the result as soon as the check fails.

Note 1: Array.some() will return true whenever a check returns true. Array.every() will return true only if all checks return true.

Note 2: The idea behind your function seems to be return true if there's at least one null or '' value, but your code does the opposite. You can negate the result of my function to get false when there's an empty item.

Note 3: There is in another difference between Array.keys/values/entries with Array.forEach(), and a for...in loop. The for...in loop will also loop all inherited enumerable properties, while the Object.x() methods would only iterate own enumerable properties.

// use object values, I use Object.entries to show the key in the console
const checkHasEmpty = obj => Object.entries(obj).some(([key, value]) => console.log(`key: ${key}`) || value === null || value === '')

console.log(checkHasEmpty({}))

console.log(checkHasEmpty({ a: 1, b: null, c: 3 }))

console.log(checkHasEmpty({ a: '', b: 2 }))

console.log(checkHasEmpty({ a: 1, b: 2, c: null }))

Upvotes: 1

brk
brk

Reputation: 50291

It seems in the second snippet the mistake is here

Object.keys(obj).forEach(key => {
          if (obj[key] === null || obj[key] === '') {

forEach will accept argument as (item,index) where item is the element of array and index is the current index in the array.

So obj[key] will try to get the element in the array specified by the key which can also be undefined

Try this replacing obj[key] by only key or obj[index]

Object.keys(obj).forEach(key => {
          if (key === null || key === '') {

Upvotes: 0

Related Questions