Re: EcmaScript Proposal – Private methods and fields proposals.

Sultan thysultan at gmail.com
Wed Apr 18 00:31:23 UTC 2018


>Do you limit classes to creating only the private fields declared in the
class, or can they create arbitrarily named ones?

Yes, just as you could write arbitrary named fields with the mentioned WeakMap
approach, for example –

[...] private[key] = value
[...] private(this)[key] = value
[...] registry.get(this)[key] = value

and retrieve arbitrary fields

[...] private[key]
[...] private(this)[key]
[...] registry.get(this)[key]

>The full form is expr.#foo, where expr can be `this` or some other
expression appropriate in front of a dot. The #foo binds to the innermost
enclosing class that has a private field called foo. If expr doesn't
evaluate to an instance of that class, you fail and throw.

Is this what you meant?

class A {
  #foo = 1
  constructor() {
    let self = this

    this.B = class B {
      constructor() {
        self.#foo = 2
      }
    }
  }
  get() {
    return this.#foo
  }
  run(program) {
    return eval(program)
  }
}

let a = new A()
let b = new instance.B()

Would this return 1 or 2 or would the previous statement throw?

console.log(a.get())

Additionally would this work

a.run('this.#foo = 3')

---

A similar symmetry can be remarked with regards to:

class A {
  private foo = 1
  constructor() {
    const self = this

    this.B = class B {
      constructor() {
        private(self)["foo"] = 2
      }
    }
  }
  get() {
    return private.foo
  }
  ...
}

On Wed, Apr 18, 2018 at 2:32 AM, Waldemar Horwat <waldemar at google.com>
wrote:

> On 04/17/2018 02:26 PM, Sultan wrote:
>
>> In the transpilation you created the field using "registry.set(this, {id:
>>> 0})"
>>> in the constructor.  If you then claim that any write to the field can
>>> also create it, then you get the hijacking behavior which you wrote doesn't
>>> happen.
>>>
>>
>> The difference between
>>
>> class A {
>>    private id = 0
>> }
>>
>> and
>>
>> class A {
>>    constructor() {
>> private.id <http://private.id> = 0
>>    }
>> }
>>
>> is the likened to the difference between
>>
>> (function (){
>>    var registry = WeakMap()
>>
>>    function A () {
>>      registry.set(this, {id: 0})
>>    }
>>
>>    return A
>> })()
>>
>> and
>>
>> (function () {
>>    var registry = WeakMap()
>>
>>    function A () {
>>      registry.set(this, {})
>>      registry.get(this)["id"] = 0
>>    }
>>
>>    return A
>> })
>>
>> I don't see how this permits the hijacking behavior previously mentioned,
>> that is –
>>
>> (new A()).write.call({}, 'pawned');
>>
>> Would still fail in the same way for both of these variants.
>>
>
> OK; you split creation into two phases.  That's fine.  Do you limit
> classes to creating only the private fields declared in the class, or can
> they create arbitrarily named ones?
>
> They just lexically scope the private names in their own separate
>>> namespace.  #foo refers to the innermost enclosing class that has a private
>>> field called foo.
>>>
>>
>> I'm not sure i understand, Does #foo refer to this.#foo? Can you post a
>> fleshed out example of this?
>>
>
> The full form is expr.#foo, where expr can be `this` or some other
> expression appropriate in front of a dot.  The #foo binds to the innermost
> enclosing class that has a private field called foo.  If expr doesn't
> evaluate to an instance of that class, you fail and throw.
>
> Read the proposals.
>
>     Waldemar
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180418/9bc22c8a/attachment.html>


More information about the es-discuss mailing list