-
Notifications
You must be signed in to change notification settings - Fork 3
Hidden members in object literals? #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Great question! I've been pondering this all afternoon and I'm still not confident in my answer. I'll have to think on it a little more. For now, I'll make the following observations:
|
Another option would be to allow hidden methods, but not instance variables, in object literals. We would then have an interestingly isomorphic relationship between class definitions and object factories: function makeObject() {
let a, b;
return {
someMethod() {}
hidden helperMethod() {}
};
} class C {
var a, b;
someMethod() {}
hidden helperMethod() {}
} This would also preserve the clear distinction between instance variables and hidden methods that I like. |
For now, I'll just say two things: I don't think it's about There is a strong semantic parallel between object literals and the |
I think I've convinced myself that hidden methods should be allowed on object literals. The same arguments that motivate hidden methods in classes also apply to anywhere else we can find method definitions. The argument is: It should be possible to transparently decompose methods without altering the observable interface of the object upon which those methods are defined. I'm still less certain of whether we should allow instance vars on object literals. |
Any place you (declaratively) define an object it should be possible to choose which part of its encapsulated state is protected from external tampering. |
I think I can add some additional support to the case for hidden methods in object literals. Hidden methods in object literals enables secure, transparent method decomposition for object literal mixins: let mixin = {
hidden helper() { console.log('hello') },
sayHello() { this->helper() }
};
Object.assign(obj, mixin);
obj.sayHello(); // 'hello' |
Yes, cool. But that won't work if the mixin needs to access instance variables. For that you need: let mixin = sup => class {
var msg;
hidden helper() { console.log(this->msg) },
sayHello() { this->helper() }
constructor() {
this->msg="hello";
}
};
let obj = new class extends mixin() {};
obj.sayHello(); |
Whoa, @allenwb I just fixed the indentation in your comment above. I had no idea git lets me edit your comments. Scary! Did you get notified that someone altered your comment? |
If hidden state in object literals is per object, rather than per enclosing declaration thing as in #7 (comment) , what utility does it provide over lexical variables? Btw, I remain fascinated by this issue, but I do not actually advocate #7 (comment) . The argument I make there is "too clever". |
This example of hidden methods is really about trying to regain some of the ground we lost when infix |
What if we get rid of hidden methods, allow lexical functions inside classes (even if it is only functions), and re-introduce infix |
I've spent some time thinking about this topic. I actually included this in an early draft of the "unified class features" explainer, but later removed it. The conclusion I've come to is that hidden methods and instance variables in object literals would be great, but there are two use cases:
(There are some use cases for instance variables in object literals that will never work, such as in a Bootstrap-style class system. We'll just have to take this as a sunk cost as a result of several other goals that are shared among the instance variables and private fields proposals.) Recently, a few people including Justin, Axel and Yehuda have been discussing how to move forward on private name declarations outside of classes. This is the core of addressing the second case. I'd rather not add instance variables/hidden methods to object literals until we have this worked out, since I think the second case is very common and important (unlike for classes, where you can generally get by without that). |
That was exactly the solution that I presented in Paris in 2015. If I recall correctly, there was significant push-back against using function declarations as internal methods in this way. At the time (and I believe this is still the case), there was concern about relying so heavily on There are other advantages to using
The added functionality is the ability to support "extension" methods outside of class contexts. I would still like to see us explore the extension method idea, but in a way that does not run afoul of the concerns above. |
This is just one example of what the Max-min Classes 1.1 proposal is reacting to. TC39 currently has an continuing stream of actual and potential class related proposals, each having to fit in with already committed proceeding proposals. (I call that "kick the ball down the field design") Instead we suggest that we identify and provide the most minimal set of essential functionality that is still missing from class definitions. Then stop! Be finished with classes for the next 10 years. JS has always been a minimalist language. |
Closing in preparation for public review. Please feel free to continue discussion or open a new issue for a specific topic. |
Uh oh!
There was an error while loading. Please reload this page.
It would seem that instance variables and hidden methods from #7 could be easily adapted to object literals. Consider:
or alternatively
I think this might be a further selling point to this approach. Programmers who prefer object literals to class definitions also get functionality of hidden state and methods .
The text was updated successfully, but these errors were encountered: