1 of 15

Shu-yu Guo, Google for

Tab Atkins, Google

2 of 15

Relative Indexing is Kinda Nice

In Python, list[-N] returns the Nth item from the last item of the list.

Pretty ergonomic; Array#slice and Array#splice already supports relative indexing.

In JS, you can write arr[arr.length - N], but:

  • Verbose
  • Have to give a name to the indexable: str.split(' ')[-1] would sure be nice

3 of 15

We Can’t Have It as Syntax

In JS,

o[1] is just o["1"],

And, alas,

o[-1] is just o["-1"].

4 of 15

The Proposal

function item(n) {

n = %ToInteger(n);

if(n >= 0) {

return this[n];

}

return this[this.length+n];

}

Object.defineProperty(

Array.prototype,

"item",

{ value: item,

writable: true,

enumerable: false,

configurable: true });

// Ditto for String,

// TypedArrays

5 of 15

Why We Should Name It .item()

A rare chance of confluence with Web APIs.

First, some background and history...

6 of 15

Web APIs Have Weird Bespoke Array-likes

7 of 15

An ObservableArray to Rule Them

WebIDL recently added ObservableArray: a Proxy of Array that lets web spec authors to trap Array MOP operations

Almost a drop-in replace weird bespoke Array-likes

Catch is: weird bespoke Array-likes all have .item(), itself a Java-ism

8 of 15

Compat Risk: Userland Libraries

  • MooTools
  • Ext
  • Prototype

None of them have a .item(), so cautiously optimistic

9 of 15

Compat Risk: Existing Web API .item()

Web API .item(N)

Proposed JS .item(N)

N is +Infinity or -Infinity

N = 0

N left as-is

N < 0 or N > 2^32

N = N mod 2^32

N left as-is

N is OOB

Returns null

Returns undefined

10 of 15

Compat Risk: Existing Web API .item()

Web API .item(N)

Proposed JS .item(N)

N is +Infinity or -Infinity

N = 0

N left as-is

N < 0 or N > 2^32

N = N mod 2^32

N left as-is

N is OOB

Returns null

Returns undefined

Risk assessment: very low

11 of 15

Compat Risk: Existing Web API .item()

Web API .item(N)

Proposed JS .item(N)

N is +Infinity or -Infinity

N = 0

N left as-is

N < 0 or N > 2^32

N = N mod 2^32

N left as-is

N is OOB

Returns null

Returns undefined

Risk assessment: slight for N < 0, very low for N > 2^32

12 of 15

Compat Risk: Existing Web API .item()

Web API .item(N)

Proposed JS .item(N)

N is +Infinity or -Infinity

N = 0

N left as-is

N < 0 or N > 2^32

N = N mod 2^32

N left as-is

N is OOB

Returns null

Returns undefined

Risk assessment: moderate

13 of 15

De-risking

Chrome is willing to gather data on existing uses of WebIDL .item()

14 of 15

If incompat arises,

then we bikeshed name

15 of 15

Stage 1?

Specifically,

  • To explore solution space for relative indexing
  • Strong preference for the method .item(), pending compat data