-1

Suddenly, I am seeing a strange behavior. Here is a snippet:

// attributesList is an object with properties 0, 1, 2.
for (var j in attributesList) {
   // this loop should run 3 times.
   var attribute = attributesList[j];
}

As you can see from above, the loop should run 3 times. But for some very strange reason it is being run 4 times. For the last iteration the value of j == "seek".

Even stranger, this same code base works on another git branch (no changes). This only seems to happen when I run this from a particular git branch.

Is there any logical explanation for this mysterious "seek" property? One thing I tried looking into is perhaps javascript version and any other versioning differences... but no luck here.

* Updated *

attributesList is an array of object type.

AlvinfromDiaspar
  • 6,611
  • 13
  • 75
  • 140
  • 1
    Sure. At some point, that object was given a `seek` property. Try doing a search across your entire code base for `.seek`, `seek:`, `'seek':` or `"seek":` – Mike Cluck Sep 09 '16 at 17:14
  • @Mike. This was my first thought. But when I evaluate the attributesList during run/debug time I do not see any property called "seek". – AlvinfromDiaspar Sep 09 '16 at 17:17
  • Then either you aren't viewing it correctly, since it clearly has such a property, or it's inherited the property at an earlier point in it's prototype chain that you aren't immediately seeing. – Mike Cluck Sep 09 '16 at 17:18
  • 1
    Re your edit: You ***really*** don't want to add that to your question. It will achieve nothing positive, and in any case, meta content doesn't go in questions. I've removed it for you. – T.J. Crowder Sep 09 '16 at 17:19
  • 1
    "attributesList is an array of object type" So is it just an array which contains objects? Or is it an object that you are treating as an array? – Mike Cluck Sep 09 '16 at 17:23
  • It is literally an array. – AlvinfromDiaspar Sep 09 '16 at 17:25

1 Answers1

2

The object in question has four enumerable properties. It probably inherits seek from its prototype object, which is why you think it only has three properties.

Your comment to MikeC adds weight to that:

when I evaluate the attributesList during run/debug time I do not see any property called "seek"

As does your update:

attributesList is an array of object type.

That tells us that somewhere in your codebase (probably in a plugin), someone has been very naughty and added an enumerable property to Array.prototype. They can do that with various different syntaxes; if it's just the one property (seek), it's probably like this:

Array.prototype.seek = function() {
    // ...
};

That's poor practice, they should have made it non-enumerable:

Object.defineProperty(Array.prototype, "seek", {
    value: function() {
        // ...
    }
});

But fundamentally, for-in is not for looping through arrays. See my other answer here for how to loop through arrays.

Two excerpts from that long answer:

Use forEach:

attributesList.forEach(function(attribute) {
   // ...
});

or if you really want to use for-in, add a hasOwnProperty check:

for (var j in attributesList) {
   if (attributesList.hasOwnProperty(j)) {
      // this loop should run 3 times.
      var attribute = attributesList[j];
   }
}

or of course use a for loop. See the answer for details.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I thought about using .hasOwnProperty( ). But what if I want to iterate over properties which has been inherited? – AlvinfromDiaspar Sep 09 '16 at 17:24
  • btw, it does looks like "seek" is being inherited. It is actually some kind of built-in function or something. – AlvinfromDiaspar Sep 09 '16 at 17:29
  • @AlvinfromDiaspar: No, JavaScript arrays have no built-in `seek` method. – T.J. Crowder Sep 09 '16 at 17:30
  • @AlvinfromDiaspar: *"what if I want to iterate over properties which has been inherited"* Arrays get no enumerable properties from their prototype by default. It's only when people do silly things such as I called out in my edit just now that they get enumerable properties. – T.J. Crowder Sep 09 '16 at 17:31
  • What is weird is that the object is definitely an array. I am inserting (pushing) objects/strings to the array. This is what I observed: the 1) Array is created. 2) An object is inserted. 3) I observe the array object... and I see that it has the first object (index 0) AND there is a prototype property. – AlvinfromDiaspar Sep 09 '16 at 18:19
  • @AlvinfromDiaspar: It's not weird at all. As I said in the answer, clearly someone's added `seek` to `Array.prototype`. – T.J. Crowder Sep 10 '16 at 07:38
  • I don't think anybody is adding "seek". It turns out "seek" is a function that exists way up in the prototype chain. The weird thing is that this words in other git branches. – AlvinfromDiaspar Sep 14 '16 at 18:38
  • @AlvinfromDiaspar: Something, somewhere, is absolutely adding `seek`, and doing so in a very pre-2009 way (2009 was when `defineProperty` was added, allowing non-enumerable properties to be added). As for "way up" in the prototype chain: It's on `Array.prototype` or `Object.prototype`. Those are the only two objects in an array's prototype chain. – T.J. Crowder Sep 14 '16 at 21:30