But how do I add to array prototype without it being triggered in the for..in?
By adding it as a non-enumerable property, via Object.defineProperty
. Non-enumerable is the default, so:
Object.defineProperty(Array.prototype, "sum", {
value: function() {
// ...implementation of sum
}
});
...but if we wanted to be explicit, we'd have enumerable: false
:
Object.defineProperty(Array.prototype, "sum", {
enumerable: false, // <== Not necessary, false is the default
value: function() {
// ...implementation of sum
}
});
Live Example:
Object.defineProperty(Array.prototype, "sum", {
value: function() {
return this.reduce(function(acc, value) {
return acc + value;
}, 0);
}
});
var a = [1, 2, 3];
snippet.log("a.sum() = " + a.sum());
var key;
for (key in a) {
snippet.log("key = " + key);
}
snippet.log("Note that 'sum' did not show up as a key");
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
All modern browsers support Object.defineProperty
, which was part of the 5th edition specification released in 2009. IE8 does not, as it predates the specification.
Side note: I don't recommend using for-in
to loop through arrays, whether you add non-entry properties to Array.prototype
(or the array itself) or not. I recommend the various alternatives in this answer. But you've said you're using a library that does it and doesn't have the necessary hasOwnProperty
check (which makes it a poorly-written library) and can't change that, so... The above is how you add to Array.prototype
without the additions showing up in for-in
.