1

Can you explain me this?

JAVASCRIPT

if (typeof Array.prototype.contains != 'function') {
    Array.prototype.contains = function (str){
        return this.indexOf(str) > -1;
    };
}

var text = "Hello world";
var tokens = text.split(" ");
console.log(tokens.length);
for (var i in tokens){
    console.log(tokens[i]);
}

OUTPUT

2
"Hello"
"world"
function ()

In other words, the "contains" function i added to the Array prototype appears in the for loop as last element (but the array length is 2). Why?

Oneiros
  • 4,328
  • 6
  • 40
  • 69
  • Because every property created through assignment is *enumerable* and `for/in` iterates over all enumerbale properties. – Felix Kling May 12 '15 at 13:51

1 Answers1

3

Why?

Because for-in doesn't loop through array entries, it loops through enumerable properties of an object. You've created a new enumerable property on Array.prototype, and so that property shows up in for-in loops on any array.

The solutions are:

  1. Don't do that, instead loop through arrays in any of several ways that don't have that problem, or

  2. Use hasOwnProperty to filter out inherited properties (see link above for more), or

  3. Define contains as a non-enumerable property via Object.defineProperty or similar (you can only do this on ES5+ engines, it cannot be shimmed).

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875