proposal-array-last
proposal-array-last copied to clipboard
Simplified polyfill
Here's a simplified zero-dependency polyfill supporting all environments as far back as ES6, derived from the official polyfill at the time of writing.
const O = Object
const floor = Math.floor
function last(value, fallback) {
if (value != null) {
const l = +value.length
if (l === l) {
if (l > 9007199254740991) return 9007199254740990
if (l >= 1) return floor(l) - 1
}
}
return fallback
}
function install(name, desc) {
if (Object.getOwnPropertyDescriptor(Array.prototype, name) == null) {
Object.defineProperty(Array.prototype, name, desc)
}
}
install("lastItem", {
enumerable: false,
configurable: false,
get() {
const l = last(this, -1)
if (l >= 0) return this[l]
},
set(value) {
// The coercion is so it doesn't throw in strict mode and has the
// correct observable behavior WRT indexed property setters.
O(this)[last(this, 0)] = value
},
})
install("lastIndex", {
enumerable: false,
configurable: false,
get() { return last(this, 0) },
})
This issue is purely informational, and no action here is needed. I just wanted to elaborate a bit upon the "There are polyfills which could use less code." part of this section of the README.
I’m not clear on why the object coercion is needed; a strict mode getter should be prepared to handle primitive receivers.
@ljharb I fixed the comment to clarify I meant invoking setters without throwing, not getters. It matters in that 0[0] = 1 throws in strict mode, but Object(0)[0] = 1 doesn't, and the README spec polyfill uses explicit object coercions for all methods, so I had to include it.