Extending Built-in Prototypes
ID |
javascript.no_extend_native |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
best-practice, reliability |
Description
Reports assignments that mutate the prototype of a built-in global object — Array.prototype.foo = …, String.prototype.bar = function () { … }, Object.prototype["x"] = …, etc. Any property added this way is visible to every script in the same realm, including third-party libraries that did not opt in.
Rationale
Patching native prototypes:
-
leaks new enumerable properties into every
for…inloop andObject.keyscall, -
fights with future ECMAScript additions of the same name (the standard wins, your override silently breaks at the next runtime upgrade),
-
defeats polyfill detection (
if (!Array.prototype.flat) { … }will now skip your polyfill but execute against an incompatible custom version), -
spreads the mutation across the whole module graph, so isolated tests no longer represent reality.
// Bad - global mutation
Array.prototype.first = function () { return this[0]; };
String.prototype.reverseWords = function () { ... };
Remediation
Use a wrapper, a free-standing utility function, or a subclass — keep your additions out of the global prototype chain.
// Good - utility function
const first = (arr) => arr[0];
// Good - subclass
class CollectionList extends Array {
first() { return this[0]; }
}