JavaScript For loop vs for in does not work

2019-09-19 13:33发布

I wrote two functions named some and every to expect to get results shown as below:

console.log(every([NaN, NaN, NaN], isNaN));
// → true

console.log(every([NaN, NaN, 4], isNaN));
// → false

console.log(some([NaN, 3, 4], isNaN));
// → true

console.log(some([2, 3, 4], isNaN));
// → false

My functions are:

function every(array,predicate){
  for (var element in array){
    if (!predicate(element))
      return false;
  }
  return true;
}

function some(array, predicate){
  for (var element in array){
    if (predicate(element))
      return true;
  }
  return false;
}

But the results are all false

Once I change the for...in to for loop, the answers are correct.

function every(array, predicate) {
  for (var i = 0; i < array.length; i++) {
    if (!predicate(array[i]))
      return false;
  }
  return true;
}

function some(array, predicate) {
  for (var i = 0; i < array.length; i++) {
    if (predicate(array[i]))
      return true;
  }
  return false;
}

Why for..in can not result in the correct answer?

2条回答
你好瞎i
2楼-- · 2019-09-19 14:23

If you don't want to use a traditional for loop, consider using a for…of loop, which iterates through the elements in an array. for…in iterates through the keys.

function every (array, predicate) {
    for (var element of array) {
        if (!predicate(element)) {
            return false;
        }
    }
    return true;
}

docs for for…of

Note: per the documentation, this requires an implementation that runs the ES6 Harmony proposal.

查看更多
Juvenile、少年°
3楼-- · 2019-09-19 14:23

for..in iterates through the property names of the object you are iterating over.

In this case, those would be 0, 1, 2, so your attempt is calling the predicate on those and not the actual array elements.

Don't use for..in with arrays. The order of iteration is not guaranteed and it can wind up iterating over non-index properties.

查看更多
登录 后发表回答