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

Tom Barrasso tom at barrasso.me
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
operator?

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

```js
class UnrolledLinkedList {
  constructor(nodeCapacity = 8) {
    // ...
  }

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

let list = new UnrolledLinkedList();
list.add(1);
list.add(2);
list.add(3);

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.

Tom



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

>
>
> Le 9 mai 2019 à 23:17, Tom Barrasso <tom at barrasso.me> 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: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190510/addb38e1/attachment.html>


More information about the es-discuss mailing list