Proposal: Symbol.inObject well-known symbol to customize the "in" operator's behavior

Tom Barrasso tom at
Fri May 10 13:40:50 UTC 2019

There are obvious limitations given the masking/ overwriting of the default
implementation, but are these limitations not also true for other symbols
like `Symbol.hasInstance`? If overwritten (including in a prototype chain),
it then masks the original behavior of the `instanceof` operator. Symbols
are one way to do this more explicitly and without the caveats of needing
to use a Proxy everywhere.

Any symbol that allows for reconfiguring/ overloading an operator risks
breaking the assumptions about how that operator is supposed to behave.
Perhaps I’m not understanding some way this is different/ more significant
for overloading the `in` operator than say `instanceof` or the spread

Perhaps a more reasonable use case than prototyping String would be a
user-defined, iterable data structure like an unrolled linked list?
Even with `Proxy` this is not possible unless we wrapped all constructor

class UnrolledLinkedList {
  constructor(nodeCapacity = 8) {
    // ...

  [Symbol.inObject](index) {
    return (index >= 0 && index <= this.length)

let list = new UnrolledLinkedList();

if (1 in list) {
  // ...

A developer may want to mimic the behavior of `Array`, but using a `Proxy`
would require wrapping all constructor calls or calls to the `in` operator.
The other alternative is to set numeric properties on the list, but doing
so isn't always possible for every data structure.


On Fri, May 10, 2019 at 1:23 AM Claude Pache <claude.pache at> wrote:

> Le 9 mai 2019 à 23:17, Tom Barrasso <tom at> a écrit :
> If this Symbol were seriously considered I believe it would expand the
> meaning of the in operator as you’re correct, this is definitely not it’s
> current intention.
> The `in` operator has a well-defined meaning, that *by design* you can’t
> ignore even with the fanciest proxy. (And no, there is no hope for
> introducing a new mechanism that allows to overcome those limitations,
> since they are by design.)
> Consider for example the following proxy around a String object:
> ```js
> function conflateInAndIncludes(str) {
>     return new Proxy(Object(str), {
>         has(target, key) { return str.includes(key) }
>     })
> }
> var FrankensteinFood = conflateInAndIncludes("food");
> "foo" in FrankensteinFood // true, yeah!
> "bar" in FrankensteinFood // false, yeah!
> "length" in FrankensteinFood // TypeError: proxy can't report a
> non-configurable own property '"length"' as non-existent
> ```
> —Claude
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list