Array.prototype.myFeature = function() {};
var arr = ['some', 'items'];
for (var prop in arr) {
console.log(prop);
}
Array.prototype.myFeature = function() {};
var arr = ['some', 'items'];
for (var prop in arr) {
console.log(prop);
}
The output for that code will be: 0
, 1
, myFeature
.
The question is: why only custom added function to the Array
prototype is outputed, instead of all the function that exists in prototype?
-
1
Two things I wanted to point out: first that adding your own functions to native prototypes is considered bad practice, and that normal functions which accept the array as an argument should be preferred. Secondly, arrays shouldn't be looped over using
for..in
, only using.forEach
, or afor..of
loop, as, withfor..in
, the order can't be guaranteed, and you run into issues like this. – kingdaro Commented Apr 16, 2018 at 16:17 - 4 Related reading: Why is using “for…in” with array iteration a bad idea? (it's slow, order is not preserved, and you get all enumerable properties) – apsillers Commented Apr 16, 2018 at 16:18
- @kingdaro pletely agree with you, but it was just for testing. I wanted to know why is that happening. – Src Commented Apr 16, 2018 at 16:19
-
1
Closely related: How to define method in javascript on
Array.prototype
orObject.prototype
so that it doesn't appear in for in loop – Bergi Commented Apr 16, 2018 at 18:32
2 Answers
Reset to default 18This is because built-in array methods are defined to be non-enumerable, while properties created by ordinary assignment are enumerable. Internally, properties have behavioral features specified by their associated property descriptor which is defined at property-creation time. One feature supplied in this way is the property's enumerability.
Compare
> Object.getOwnPropertyDescriptor(Array.prototype, "join")
{value: ƒ, writable: true, enumerable: false, configurable: true}
and
> Object.getOwnPropertyDescriptor(Array.prototype, "myFeature")
{value: ƒ, writable: true, enumerable: true, configurable: true}
The first property descriptor object has enumerable: false
while the second has enumerable: true
. Non-enumerable properties are not enumerated in for-in loops.
You can define your own non-enumerable property with Object.defineProperty
:
Object.defineProperty(Array.prototype, "myFeature", { value: function() {}, enumerable: false });
Per the docs:
The
for...in
statement iterates over the enumerable properties of an object. For each distinct property, statements can be executed.
Seems, only these three properties are enumerable. So for...in
only iterates over them.