This 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 });