1

I'm writing an extension method for Array which accepts a function and then call it for each items in the Array.

It works fine except the extension itself is added into the Array after the function call. So at the alert part, the third alert shows my foo function in string.

Here's the code:

Array.prototype.foo = function (F) {
    for (var i in this) {
        this[i] = F(this[i]);
    }
}

var items = ["a", "b"];

items.foo(function (data) {
    return data + 1;
});

for (var i in items) {
    alert(items[i]); // expected to see a1 and b1 but also displayed foo as string.
}
2
  • Iterate over the array content, not its properties. Commented Dec 1, 2011 at 20:22
  • Just a style issue but I wouldn't use a capital F for the function variable's name, go for something like fn. Commented Dec 1, 2011 at 20:26

4 Answers 4

4

That's because for in is going through the keys of the array, not the elements. You'll want to switch your loop (I believe):

for (var e = 0; e < this.length; e++){
  // call against this[e] now
}

For example:

var ary = ['a','b','c']
for (var a = 0; a < ary.length; a++){
  console.log(ary[a]); // echos a, b, c
}

var obj = {a:'X',b:'Y',c:'Z'}
for (var a in obj){
  console.log(a);     // echos a, b, c
  console.log(obj[a]) // echos X, Y, Z
}
Sign up to request clarification or add additional context in comments.

Comments

2

I +1'd Brad Christie's answer, but I wanted to add that it is possible, starting in JavaScript 1.8.5, to create a property that does not show up in for(var ... in ...) statements, by using the defineProperty method. That would look like this:

Object.defineProperty
(
  Array.prototype,
  'foo',
  {
    value:
      function (f)
      {
        for (var i = 0; i < this.length; ++i)
          this[i] = f(this[i]);
      }
  }
);

var items = [1, 2, 3];
items.foo(function (n) { return 2 * n; }); // now items = [2, 4, 6]
for (var i in items)
  alert(items[i]); // alerts 2, then 4, then 6

That said, JavaScript 1.8.5 only came out in 2010, so it might not be a good idea, yet, to write code that depends on it.

Comments

0

That is expected from the 'for the for(var in items)' as it enumerates through object fields, not indexes.

Comments

0

If you had intended to loop over the object fields you could add a typeof(this[i]) != 'function' check before your assignment.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.