Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript for ... in loop with Object.prototype and Array.prototype properties [duplicate]

Tags:

javascript

I am reading MDN docs for better understanding javascript. This is an excerpt from there

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}

In the worst case i thought it is going to print 0, 1, 2, "foo", "arrCustom" but it also prints objCustom.

Update:
1) How can i visualize the prototype chain from iterable to Array all the way upto Object. Like is there any iterable.getParent method or iterable.myparent property which points to parent on it.
2) why it does not print array functions such as toString, sort they are also on Array.prototype.
3) Do i need to use hasOwnProperty always when someone add something to Array.prototype property.

like image 725
Srinivas Avatar asked Aug 24 '17 00:08

Srinivas


People also ask

Which JavaScript loop loops through the properties of an object?

Description. The loop will iterate over all enumerable properties of the object itself and those the object inherits from its prototype chain (properties of nearer prototypes take precedence over those of prototypes further away from the object in its prototype chain).

What's the difference between prototype and __ proto __ in JavaScript?

prototype is a property of a Function object. It is the prototype of objects constructed by that function. __proto__ is an internal property of an object, pointing to its prototype.

How many properties does a prototype object have in JavaScript?

prototype . As seen from the above image prototype property of the function is an object (prototype object) with two properties: constructor property which points to Human function itself.

Can you loop through an object JavaScript?

Object. key(). It returns the values of all properties in the object as an array. You can then loop through the values array by using any of the array looping methods.

What is the use of prototype in JavaScript?

The Object.prototype is on the top of the prototype inheritance chain: Date objects, Array objects, and Person objects inherit from Object.prototype. Sometimes you want to add new properties (or methods) to all existing objects of a given type. Sometimes you want to add new properties (or methods) to an object constructor.

How do you loop over an array in a prototype?

Instead, use a for loop for looping over an array. The properties iterated with for-in loop also includes the properties of the objects higher in the Prototype chain. The order in which properties are iterated may not match with the properties that are defined in the object.

What do all JavaScript objects inherit from a prototype?

All JavaScript objects inherit properties and methods from a prototype: Date objects inherit from Date.prototype Array objects inherit from Array.prototype Person objects inherit from Person.prototype

How to loop through the properties of an object in JavaScript?

The JavaScript for in statement loops through the properties of an Object: The JavaScript for in statement can also loop over the properties of an Array: Do not use for in over an Array if the index order is important. The index order is implementation-dependent, and array values may not be accessed in the order you expect.


Video Answer


2 Answers

It's because a for in loop is meant to iterate all enumerable properties, both owned and inherited. You can use Object.keys() to get only owned properties.

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

Object.keys(iterable).forEach(function(key) {
  console.log(key); // logs 0, 1, 2, "foo"
});

However, it's pretty unusual to put non-numeric properties on an Array. There are usually better ways to accomplish whatever it is you need to do.

It's also unusual to use a for in loop on an Array. There are other, better ways of iterating an Array, as long as you keep it limited to its numeric indices.


1) "How can i visualize the prototype chain from iterable to Array all the way upto Object. Like is there any iterable.getParent method or iterable.myparent property which points to parent on it."

You can use Object.getPrototypeOf() to get the next object an object inherits from. Do it in a loop to go until null is reached.

var proto = Object.getPrototypeOf(myObj);
do {
  console.log(proto);
} while((proto = Object.getPrototypeOf(proto)));

2) "why it does not print array functions such as toString, sort they are also on Array.prototype."

toString() and other built in methods are non-enumerable. As I noted above, for in only reaches enumerable properties.

3) "Do i need to use hasOwnProperty always when someone add something to Array.prototype property."

Don't use for in loops on Arrays, and you'll do better. But yes, if you use for in, you'll need .hasOwnProperty() boilerplate code to guard against that.

You should also be aware that there's no guarantee that Array indices will be reached in order when using for in. And it's also usually much slower that other means of Array iteration. It's especially slow with the .hasOwnProperty() check.

like image 130
spanky Avatar answered Oct 29 '22 01:10

spanky


Because for-in iterates through all the properties of the object, including the ones inherited from the prototype. To skip the inherited properties, use hasOwnProperty().

Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i);
  }
}
like image 39
Barmar Avatar answered Oct 28 '22 23:10

Barmar