Monkey-patching a built-in prototype (Array.prototype.last = ...) changes every array in the program, including ones created by other libraries. Don't do it in application or library code:
- Enumerability. Plain assignment creates an enumerable property, so
for...inover any array (or object, if you patchedObject.prototype) now yields your key. Built-in methods are non-enumerable. - Collisions. Two libraries adding the same name overwrite each other, and the name may later be standardised with different semantics.
- Web compatibility pressure. Existing sites constrain what the language can do. TC39 wanted
Array.prototype.containsbut renamed itincludes(2014) because the name wasn't web-compatible. The proposedflattenshipped in Firefox Nightly and broke sites using MooTools, which defined its own enumerableflattenand copied every key ofArray.prototypeonto itsElementswithfor...in. Once the native, non-enumerableflattenexisted, assigning to it didn't make it enumerable, so the copy skipped it. The method was renamedflat(the "SmooshGate" episode). - Hidden coupling. Behaviour depends on which scripts loaded first, and code that iterates with
for...inbreaks without any visible change in that code.
Alternatives: a standalone function (last(array)), a wrapper or subclass you own, or a module-local helper.
The exception is a polyfill: code that adds a standardised feature missing from old runtimes. A safe one feature-tests first (if (!Array.prototype.at)), follows the spec's behaviour, and defines the property with Object.defineProperty so it is non-enumerable like the built-ins. Prefer an existing, maintained polyfill over writing your own.