javascript-private-state icon indicating copy to clipboard operation
javascript-private-state copied to clipboard

Why?

Open usergenic opened this issue 10 years ago • 13 comments

Not to be pedantic, but the README doesn't dedicate any text to the reason for adding private state to JavaScript. What's the problem you are trying to solve, in JavaScript, by adding private state?

usergenic avatar Nov 11 '15 21:11 usergenic

One thing to point out is that JS already has private state. All of the built-in constructors create objects which have "internal slots", essentially the same thing as the private slots presented here.

The main reason for private state is encapsulation. If you can limit the observable state of an object, then you have more freedom to change the implementation details without breaking existing code.

Another motivation is to provide us with a way to "self-host" the built-ins, for example to implement Promise from within JavaScript itself.

Yet another motivation is that, if we do this right, engines may be able to optimize objects with private state by virtue of their "fixed" internal shape.

zenparsing avatar Nov 11 '15 22:11 zenparsing

Another motivation is the desire to create "defensible classes", essentially classes whose invariants are immune from attack by users of the class.

zenparsing avatar Nov 11 '15 22:11 zenparsing

What would the testing story be for private state?

usergenic avatar Nov 11 '15 23:11 usergenic

@brendan private things generally shouldn't ever be tested, so the testing story would be the same as always: test the public interface and semantics.

ljharb avatar Nov 12 '15 04:11 ljharb

Would private state imply there is new support needed for object cloning?

usergenic avatar Nov 12 '15 05:11 usergenic

I say this given reliance on proposed ES6 built-ins such as Object.assign https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

usergenic avatar Nov 12 '15 06:11 usergenic

I guess the implementer of the class would need to provide their own mechanism-- but it might be worth promoting a best practice or convention for performing private data propagation when cloning.

usergenic avatar Nov 12 '15 06:11 usergenic

yep, readme needs good explanations of motivation in this proposal. with good examples where private state will be really helpful. not like "i want this only cause i have this in java". one of the core feature of javascript is the ability to modify any 3d party code. in 2015 many es6 features was successfully shipped in nodejs, but many librarys still had not modified their API and i have possibility, for example, to monkey-patch API to using promises and not break my flow in code. adding privates and protected fields break biggest js core feature. you can not use duck typing if your library have protected fields, you should only use inheritnce. but if you want to inherit from event emitter, not from library class? how will you resolve that? at least you will need interfaces or multiple inheritance. with current js concepts private/protected fields can provide only additional pain, without any benefits.

PinkaminaDianePie avatar Dec 15 '15 11:12 PinkaminaDianePie

@PinkaminaDianePie you already can't modify third-party code that's hidden in a closure, and being robust against runtime modification is the mark of a good library. Adding private and protected fields just provides different ways to encapsulate your code.

ljharb avatar Dec 15 '15 16:12 ljharb

With the improved class support in ES6 (partly) replacing IIFE's and closures for private state, many JS projects use naming to distinguish private from public state.

// super-simple example
class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  },

  area() {
    return this._calcArea();
  },

  _calcArea() {
    return this.height * this.width;
  }
}

Being able to truly hide these (without using closures) would be very useful.

sandstrom avatar Jan 23 '16 11:01 sandstrom

With these being the only ways to have private (some truly private, some not) members with ES2015 classes (all implemented as tricks), and with ES2015 classes simply being a way to remove a lot of prototype boilerplate it seems to make sense that developers using the class syntax should have available to them methods of creating private members the same way that users of the functional object creation syntax can use closures to create truly private members.

The way I see it, since closures exist and they are a way of creating private data/members, the concept of public/private already exists in javascript and not extending it to the class syntax only makes that syntax less usable. Adding it doesn't change the capabilities of the language.

Also, maybe I don't know my design pattern theory knowledge isn't great but having a clear public/private dichotomy allows for the implementation of the open/closed principal, right?

seangwright avatar Jan 27 '16 00:01 seangwright

(The concept of "private" does not exist in JavaScript - this proposal would add it)

ljharb avatar Jan 27 '16 01:01 ljharb

@ljharb Yes, you are right, but like you said the concept of 'hidden' does exist through features of the language. So, this seems like either a formalization of that concept or a way of providing an avenue for users of the language to say private instead of 'hidden' when they really want mean private.

seangwright avatar Jan 27 '16 01:01 seangwright