classes and enumerability

Allen Wirfs-Brock allen at wirfs-brock.com
Wed Dec 24 15:01:24 PST 2014


On Dec 24, 2014, at 1:49 PM, 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!
> 
> My interpretation of this data is that non-enumerability isn't important enough to bother with in the vast majority of cases.  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".
> 
> 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.

Let's drill deeper into this concern...

There are two parts of dealing with a class-abstraction, the definition the class and consuming instances of the class.  Let's look at the enumerability impact on both of those.

Class definition: In an ES5-level class abstraction library, changing the enumerability of methods might have an impact on class creation, if the attraction library does something like method copying using for-in.  However, what we are talking about is converting from an ad hoc (and possibly library provided) ES5 class abstraction to using actual ES6 class definition.  Class definitions don't depend upon reflection of properties to actually create the class.  So, I don't think we have anything to worry about on the class definition side. Enumerability of properties is irrelevant.

Class consumption:  It pretty much comes down to whether or not consumers of class instances in ES5 use for-in with or without hasOwnProperty filters to enumerate the properties of class instances.  If their ES5 code uses hasOwnProperty to filter out methods, then the fact that ES6 methods are non-enumerable will make no difference.  On the other hand, if consumers of these ES5 class instances are doing for-in enumerations and want to see inherited methods then there would be an issue. But,  other than for meta programming, it hard to imagine why they would actually want tfor-in to see any methods.

Some folks at Auburn University have been studying a large corpus of JavaScript code, see http://munawarhafiz.com/research/jssurvey/ 
On of the things they've look at is use of for-in and hasOwnProperty.  Take a look at the data shown on that page for for-in usage and read sections X and XI in the accompany paper.

Personally, I have always believed we are going down the wrong path by switching (from the original max-in class design) to making methods defined within a class definition enumerable.

The only real model of class-like abstractions that has always and universally been a part of JS is the model that the built-in constructors consistently follow. The ES6 class definition model was intended to exactly mirror that built-in model.  My vision for it was that future JS programmers should never need to worry about whether a "class" was provided by a built-in or from a library or was a local part of the application, because they all worked the same.

By make class defined methods enumerable, we parted from that simple vision and instead seem to follow the remediation path that current and legacy JS programmers had to follow because the language did not give them the capabilities they need to define classes just like the built-ins.  We're tinking too much about the past and not enough about the future.

Allen



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20141224/82b972a1/attachment-0001.html>


More information about the es-discuss mailing list