admin管理员组

文章数量:1430480

I added a method trigger to the prototype of Object:

Object.prototype.trigger = function() {
    //  ...
    return this;
};

And then have a "for in" loop:

var obj = { 4: 15, 10 : 41, 11 : 46, 12 : 51, 20 : 74 }
for( item in obj ) {
    foo( obj[item] );
}

But this loop has 6 iterations instead of 5. The last iteration is with key:

item = "trigger"

Why is the loop iterating over the __proto__ part of the object?

I added a method trigger to the prototype of Object:

Object.prototype.trigger = function() {
    //  ...
    return this;
};

And then have a "for in" loop:

var obj = { 4: 15, 10 : 41, 11 : 46, 12 : 51, 20 : 74 }
for( item in obj ) {
    foo( obj[item] );
}

But this loop has 6 iterations instead of 5. The last iteration is with key:

item = "trigger"

Why is the loop iterating over the __proto__ part of the object?

Share Improve this question edited May 16, 2019 at 17:31 Boann 50.1k16 gold badges124 silver badges152 bronze badges asked May 16, 2019 at 12:24 Alex ShulAlex Shul 5008 silver badges23 bronze badges 3
  • 1 This is how for in was written. Use hasOwnProperty to check whether it is not a proto property – Ananth Commented May 16, 2019 at 12:26
  • Put the wrong duplicate link. Anyway, for..in iterates all enumerable properties. – briosheje Commented May 16, 2019 at 12:28
  • Good source for reading - developer.mozilla/en-US/docs/Web/JavaScript/… – Pranav Kale Commented May 16, 2019 at 12:34
Add a ment  | 

4 Answers 4

Reset to default 4

for...in goes over all of the object properties without distinguishing between properties on the object itself or any of its ancestors.

In order to go over only properties defined on the object itself, you can use Object.prototype.hasOwnProperty:

const obj = { 4: 15, 10 : 41, 11 : 46, 12 : 51, 20 : 74 }
for( item in obj ) {
  if(obj.hasOwnProperty(item) {
    foo( obj[item] );
  }
}

// will ignore the trigger func and everything else defined on any prototype

for..in iterates over all enumerable properties anywhere on the prototype chain. If you want to make trigger non-enumerable so it isn't iterated over with for..in, use Object.defineProperty instead, which makes the defined property non-enumerable by default:

Object.defineProperty(Object.prototype, 'trigger', { value:  function() {
    
}});
var obj = { 4: 15, 10 : 41 }
for( item in obj ) {
    console.log(item);
}

Another way to do is to use Object.keys instead :

Object.prototype.trigger = function() {
    return this;
};

var obj = { 4: 15, 10 : 41, 11 : 46, 12 : 51, 20 : 74 }

Object.keys(obj).forEach(function(item) {
    console.log( "Key: " + item + ", value: " + obj[item] );
});

This was an error I faced with arrays some time ago. Because arrays are also objects and you could iterate down into the prototype, do not use for..in for the arrays. Your example is specific for an object that causes this issue. Instead, use standard for to iterate through the items of your object. That way you could have a cleaner and safer implementation for what you are trying to achieve, rather than using defineProperty or hasOwnProperty which are mostly used to implement reflection.

for (var i = 0; i < Object.values(obj).length; i++){
  console.log(i + ': ' + Object.values(obj)[i]);
  //foo( Object.values(obj)[i] );
}

本文标签: JavaScript Why does the quotfor inquot loop pick variables from protoStack Overflow