Question about proxies and non-class inheritance with private fields

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Question about proxies and non-class inheritance with private fields

email
Given "Private fields are designed to have semantics analogous to
WeakMaps"
(https://tc39.github.io/proposal-class-fields/#sec-private-names) and
"All ECMAScript objects, including Proxies, and any user exotic object,
should have a [[PrivateFieldValues]] internal slot iniitlaized to an
empty List."
(https://tc39.github.io/proposal-class-fields/#sec-objectcreate), does
this mean the implementation of private fields will break uses of
Object.create and Proxy usage as user-defined WeakMap implementations do
now?

For example:

```js
const priv = new WeakMap()

class Foo {
   constructor () {
     priv.set(this, 'data')
   }
   logChar () {
     console.log(priv.get(this).charAt(0))
   }
}
```

new Foo().logChar() //-> 'd'
Object.create(new Foo()).logChar() // Err: no charAt in undefined
new Proxy(new Foo(), {}).logChar() // Err: no charAt in undefined

The problem being that `this` in `logChar` for the created object and
proxy are different instances than the `this` associated with the
private map's 'data'.  So the "private slots" of those instances do not
match the objects they wrap, instead being empty/uninitialized.

I figured proxies would at least need to be able to handle situations
like this. An example on MDN shows a proxy using methods like
`setItem()` and `getItem()` from its target which, if implemented with
private data, would could cause failures like the one seen above
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#A_complete_traps_list_example).
I've seen mention of the "proxy problem" in various places with respect
to private fields but wasn't sure if there was a solution in place for
it - or even if it necessarily referred to what I'm describing here.  
But the observations above suggests that using proxies may not be safe -
at least not without familiarity with the implementation of the object
you're proxying. So I just want to make sure I understand it correctly.

Thanks,
Trevor
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about proxies and non-class inheritance with private fields

Oriol _
A proxy object emulates its target because the essential internal methods are redirected to the target by default.
However, this does not happen with other internal slots, so I don't see why it should be different for private fields.
More examples:

```js
new Number(123).valueOf(); // 123
new Proxy(new Number(123), {}).valueOf(); // TypeError: valueOf method called on incompatible Proxy
```

```js
new Set().has(1); // false
new Proxy(new Set(), {}).has(1); // TypeError: has method called on incompatible Proxy
```

```js
// Assuming a web browser
document.nodeType; // 9
new Proxy(document, {}).nodeType; // TypeError: 'get nodeType' called on an object that does not implement interface Node.
```

--Oriol

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about proxies and non-class inheritance with private fields

email
> However, this does not happen with other internal slots, so I don't see
> why it should be different for private fields.

Yup, that makes sense, and it looks like its not something I've not run
into before.  That answers my question, thanks!
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss