Rick Waldron (2014-12-13T18:44:11.000Z)
d at domenic.me (2014-12-19T22:49:30.265Z)
On Sat Dec 13 2014 at 4:54:55 AM Glen Huang <curvedmark at gmail.com> wrote: > But allowing getter & setter already makes it dangerous: > > ```js > let _bar = {} > class Foo { > static get bar() { return _bar; } > } > ``` > > Objects that have Foo.prototype in the prototype chain can do "this.bar.a > = 1", and the change won’t be shadowed. > The accessor property "bar" is _not_ created on Foo.prototype, it's created on Foo itself and would not be found on `this`. In ES5, the example above would look like this: ```js var _bar = {}; var Foo = function Foo() {} Object.defineProperty(Foo, "bar", { get: function() { return _bar; } }); ``` > I found myself looking for a way to define static properties because I > want to do this: > > ```js > function Menu(options) { > this.options = Object.assign({}, Menu.defaults, options); > } > Menu.defaults = { hidden: false }; > ``` ```js class Menu { constructor(options) { this.options = Object.assign({}, Menu.defaults, options); } static get defaults() { return Object.freeze({ hidden: false }); } } ``` This has the benefit of preventing unwanted tampering with `Menu. defaults` by ensuring that the only way to modify defaults is by explicitly providing them via `new Menu({ my opts })`. The property can be _read_ as `Menu.defaults` but assignment to `Menu.defaults` or attempts to change values or add properties will throw. > I want to expose the defaults property so it can be modified by users. > This pattern is very ubiquitous in es5. I wonder if the class syntax could > allow this pattern to be carried to es6? > ES6 is done, but this is something that I also want to revisit for ES7 (should be a year following ES6). In the meantime, it's not too painful to address this use case by doing this: ```js class Menu { constructor(options) { this.options = Object.assign({}, Menu.defaults, options); } } Menu.defaults = { hidden: true }; ``` Though I'm not sure what the benefit is to allowing any code access to an the unprotected defaults. If you and I are working on a large system using this class, with potentially many Menu components on the same page and I change the defaults, all other code can no longer trust the defaults to be correct. That said, it's not always as simple as creating a closure with the defaults so they're not exposed at all—exposing them is certainly useful for testing, and/or verifying correct, expected initial state with some baseline shape.