Behavior of non-index/out-of-range cases
hax opened this issue · 0 comments
Basically a[^i]
should have very same behavior to a[i]
(except it calculate index from the end), but we need to consider how to handle non-index case. For a[i]
, it just use i
as property, or in some cases (eg. TypedArray
), it fallback to property semantic for non-index cases. ^i
always represent index, so if it failed to calculate index, should it and how it could be fallback to normal property?
Here are the non-index (and out-of-range) cases:
a
is not an Array-like, ie.Number(a.length)
isNaN
.i
is not a numeric, ie.Number(i)
isNaN
.i
is not an integeri
is negativei
is greater thana.length
// not Array-like
let x = {0: 0, 1: 1, '-1': -1}
x[^1] // ?
x[^1] = '^1' // what will happen?
// other cases
let x = [1, 2, 3]
let v = "not-numeric" // or 0.5 (not integer), -1 (negative), 10 (> x.length)
x[^v] // ?
x[^v] = "?" // ?
Here are some possible options:
A. Always throw TypeError/RangeError for non-index/out-of-range cases
B. For Get
operation, just return undefined
, for Set
operation, silent failure
C. For Get
operation, just return undefined
, for Set
operation, throw TypeError/RangeError
D. For Get
operation, just return undefined
, for Set
operation, throw TypeError/RangeError in strict mode, silent failure in non-strict mode
E. Same as A in strict mode, same as B in non-strict mode
F. Pure syntax sugar, aka. use the exact semantic of a[a.length - i]
(though only access a
and a.length
once)
G. Use the similar semantic of Array methods (eg. at()
, slice()
)
H. Some other behavior?
My preferences is E = D > A = B = C >> F >> G.
A seems too rigor, F seems too loose (easy to introduce unexpected result or effect, eg. might add NaN
property on a
in Set
case), G is actually not the option, just for comparison.