Skip to content
This repository has been archived by the owner on Jan 25, 2022. It is now read-only.

How is this represented in property descriptors? #9

Closed
rektide opened this issue Jul 28, 2017 · 8 comments
Closed

How is this represented in property descriptors? #9

rektide opened this issue Jul 28, 2017 · 8 comments

Comments

@rektide
Copy link

rektide commented Jul 28, 2017

What is the impact of private methods/fields on the property descriptors for that method/field?

@bakkot
Copy link
Contributor

bakkot commented Jul 28, 2017

There is no way to get a property descriptor for a private field, so it doesn't come up.

@rektide
Copy link
Author

rektide commented Jul 28, 2017

I'm not in favor of making anything which can't be reflected on, or asked about. I'd like to see some capacity afforded to allow getting property descriptors, like everything else JS has ever done.

Java, C#... I can't think of a runtime that has made private so private that no one at all can reflect on the true nature of the object programmatically. It would be a critically bad decision IMO to buck this trend & make private not just private, but also invisible & undetectable.

There ought to be a way to get property descriptors for these properties that someone rightfully might want described!

@bakkot
Copy link
Contributor

bakkot commented Jul 28, 2017

some capacity afforded to allow getting property descriptors, like everything else JS has ever done

There has never been a way to reflect on closed-over variables in JavaScript, and they're an extremely core feature which is similar in many ways to this one.

Java, C#... I can't think of a runtime that has made private so private that no one at all can reflect on the true nature of the object programmatically. It would be a critically bad decision IMO to buck this trend & make private not just private, but also invisible & undetectable.

Well, that's the whole point of the proposal. Other languages are coming around to the same thing: for example one of the major features of Java 9, modules, exists in large part because they found that private state which could be reflected upon by external code wasn't good enough.

There ought to be a way to get property descriptors for these properties that someone rightfully might want described!

We might eventually add one, if there seems to be a need for it, but it won't be something which is usable from outside the class - that would defeat the entire point.

@rektide
Copy link
Author

rektide commented Jul 28, 2017

would defeat the entire point

I'd rather you make the point softly, & allow room for people who want to introspect & poke, than to make the point hard. I can't think of any forms of good that come from allowing the politics of DRM, of deciding who gets access to what, to bubble up into our everyday programming. To me, the virtue of creative use and misuse is infinite, and the principles of locking down and presuming to know how others ought use your thing are at least as likely to create problems as they are to prevent them.

There really should be some way to reflect on a class & see it's properties.

@bakkot
Copy link
Contributor

bakkot commented Jul 28, 2017

I'd rather you make the point softly, & allow room for people who want to introspect & poke, than to make the point hard.

I appreciate that point of view. Hard vs soft private - encapsulation vs reflection - is a fundamental conflict. We've had the debate at great length, both on Github and in committee, and ultimately came down on the side of encapsulation.

If you don't want to read through that issue, see this entry in the FAQ for private fields for more on why.

@Jamesernator
Copy link

@rektide Private state is mostly about versioning and updating, by disallowing access to the internals of an implementation you can guarantee that you'll always be able to update the implementation without breaking consumers.

As pointed out it's no different whatsoever to using a closure:

function counter() {
    // count is completely inaccessible to anything outside the closure
    let count = 3
    
    return {
        increment() {
            count += 1
        },
        isTen() {
            return count === 10
        },
    }
}

const c = counter()
c.increment()
// No way to access count, only what is provided on the object
// can be used to modify or get details about count

All this proposal does it make things like that easier when working with classes.


Something I will point out is that it will always be possible to break private state by modifying the source code (you could even do this programmatically with Babel or something), nothing will ever be able to prevent that.

I would even like to see a standard API for modifying JavaScript source code, but that'd require standardizing what a JavaScript AST looks like (the tree from the official grammar isn't too useful as it contains redundant information and is fairly verbose) amongst other things, so I'll stick with Babel for the time being.

@littledan
Copy link
Member

Actually, these are visible as property descriptors in the decorators proposal. No descriptors are available after the decorators run, however. If you have a class with a decorated private method like

class C {
  @decorator
  #method() {}
}

then the decorator decorator is called as

decorator({
  type: "method",
  key: PrivateName("method"),
  placement: "own",
  descriptor: {
    value: function method() {},
    enumerable: false,
    configurable: false,
    writable: false
  }
});

See more details in the decorators/private/fields integration proposal.

@littledan
Copy link
Member

Not allowing access to private methods outside the class by default, but then allowing introspection through decorators, seems to be the path forward here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants