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.