proposal-array-last icon indicating copy to clipboard operation
proposal-array-last copied to clipboard

Simplified polyfill

Open dead-claudia opened this issue 6 years ago • 2 comments
trafficstars

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.

dead-claudia avatar Aug 01 '19 15:08 dead-claudia

I’m not clear on why the object coercion is needed; a strict mode getter should be prepared to handle primitive receivers.

ljharb avatar Aug 01 '19 15:08 ljharb

@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.

dead-claudia avatar Aug 01 '19 16:08 dead-claudia