2

So there is this function

Array.prototype.containsCaseInsensitive = function(obj) {
  var i = this.length;
  while (i--) {
    if (this[i].toUpperCase() === obj.toUpperCase()) {
      return true;
    }
  }
  return false;
}

then I create this array:

ary = [0,1,2,3];
for (item in ary){
  console.log(ary[item])
}

The output is as follows:

0
1
2
3
function(obj) {
    var i = this.length;
    while (i--) {
       if (this[i].toUpperCase() === obj.toUpperCase()) {
           return true;
       }
    }
    return false;
 }

Why is the function in the iteration? Thanks!

RP-
  • 5,827
  • 2
  • 27
  • 46
David Rz Ayala
  • 2,165
  • 1
  • 20
  • 22

5 Answers5

4

Your property is enumerable (although you shouldn't enumerate the keys of an array using for ... in ... anyway).

On ES5 compatible browsers you can safely add that function as a non-enumerable property using Object.defineProperty:

Object.defineProperty(Array.prototype, 'containsCaseInsensitive', {
    value: function() {
        ...
    }
});
Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • The only problem is that version is 1.8.5 so decrease browser compatibility. In some cases, I think is still better filter the elements. – Gustavo Mar 13 '13 at 18:25
0

When you use for .. in the array is treated as an object and that is why it will show you all the properties. Use regular for to achieve the effect you want.

d4rkpr1nc3
  • 1,817
  • 13
  • 16
0

Because containsCaseInsensitive is a member of your array, and you're iterating over all members of the array. You should not write for ... in iterations to iterate over the items in an array.

David Hedlund
  • 128,221
  • 31
  • 203
  • 222
0

Because for..in outputs all the enumerable properties of an object.

If you want only the values of the array, you can use:

for (item in ary){
   if ( ary.hasOwnProperty( item ) )
      console.log(ary[item])
}

In supported environments, you can also use defineProperty to set the function as non-enumerable, like this:

Object.defineProperty( Array.prototype, 'containsCaseSensitive', {
    value: function( obj ) {},
    enumerable: false
    // ^ this is default when you use defineProperty, so you don't need it
    // but it is to show you how that works :-)
} );

However, it is usually not recommended to use for..in for arrays, you only use it for literal objects.

For arrays, it is recommended to use:

for ( var i = 0, l = arr.length; i < l; i++ ) {
    console.log( arr[ i ] );
}

Or, if supported:

arr.forEach( function( el ) {
    console.log( el );
} );
Florian Margaine
  • 58,730
  • 15
  • 91
  • 116
  • I think the "if supported" clause makes `.forEach` and even worse practice than `for ... in`, when it comes to JavaScript. The `hasOwnProperty` check works for the specific example because the property is defined at the Array object's, but it does not address issues such as `var x = [1,2]; x.prop = 'a';` – David Hedlund Jun 20 '12 at 06:46
  • Why do you think it makes it even worse practice? If you only support modern browsers, you should definitely use `forEach`, it's great and does all things. In node.js, I'd bite you if you didn't use it. – Florian Margaine Jun 20 '12 at 06:51
  • @DavidHedlund I disagree. `.forEach` is now _expected_ practice, and you should use a shim to add it for browsers that don't support it natively. In properly written ES5 code `.hasOwnProperty` is almost never needed. – Alnitak Jun 20 '12 at 06:51
0

You are iterating over all properties of the object. You need to look at this.

Community
  • 1
  • 1
phenomnomnominal
  • 5,427
  • 1
  • 30
  • 48