classes and enumerability
brendan at mozilla.org
Wed Dec 24 16:05:29 PST 2014
Kevin Smith wrote:
> Here is the summary:
> Total Files Read: 11038
> Files Containing Explicit 'enumerable: false': 149
> Occurrences of 'enumerable: false' (and variants): 206
> I love this kind of analysis - thanks!
Agreed, <3 -- thanks, Rick!
> My interpretation of this data is that non-enumerability isn't
> important enough to bother with in the vast majority of cases.
There's a confounding variable: the pain of ES6s meta-object APIs, in
It's probably true that enumerability doesn't matter enough for many
programmers, but the ES5 MOP is painful enough (both its intrinsic
complexity and ES5's indirect costs, e.g., needing to shim into
ES3-level engines) that it does not seem prudent to assume only one
cause, or to assume which cause is proximate vs. distal.
For those who care about prototype method enumerability, however many
they may be, if too few pass the ES5 hurdle (for whatever reason), then
the measurements Rick took, while informative, are not decisive.
> It *may* still be that non-enumerability is the least-surprise
> option for class methods, but certainly users don't care enough about
> the issue currently to bother with typing in "enumerable: false".
This came up on the twitter thread. If we pick a painful default, people
will still probably migrate to the shortest-path-to-joy, arguably class
syntax. In this light we can hope not to do too much harm, either way.
But what's best? I'd like to think it's non-enumerability, based on
built-ins combined with for-in from the old days. I made built-in
methods non-enumerable because that made for-in much more useful,
compared to design alternatives (built-in prototype methods enumerable;
no such thing as non-enumerable). It may be that even early JS didn't
have enough time to experiment and find an even better way, e.g.,
explicit shallow vs. deep enumeration. That adds more user-facing
complexity in choice of looping forms.
> I'm still concerned about the refactoring hazard argument. I think
> the idea is that if I change some ES5-style class into an ES6-style
> class, then I need to have good unit tests already in place to make
> sure that non-enumerability won't break things. Otherwise, I can't do
> the refactor.
> What do we think about that one?
Yehuda made the point on twitter that enumerability matters for object
literals passed to extend-ish methods, and object literals >> class
prototypes. There are many objects created from literals, some of which
are used as arguments to extend. There are few class prototypes, the
built-in ones already have non-enumerable methods, and ES6 classes are
new enough that if non-enumerable wins on balance, there won't be a
refactoring hazard to-do with extends.
Other for-in-based library code than extend could break, but would with
a built-in class that otherwise resembled the new ES6-usercode one. So
the "design of class obligations" must include choosing and coding some
enumerability non-default annotation or extra API boilerplate. Since
non-default, it will be less common, possibly rare. So back to the
"what's the best long-term default" question we cannot duck right now.
More information about the es-discuss