Enumerability is still important (was: Re: Object.define ==> Object.mixin??)

Allen Wirfs-Brock allen at wirfs-brock.com
Wed Dec 12 10:40:30 PST 2012


On Dec 11, 2012, at 10:42 AM, Herby Vojčík wrote:

> 
> 
> Allen Wirfs-Brock wrote:
>> 3) I don't see any reason that it should be restricted to enumerable
>> properties. If the intend is to deprecate enumerable along with for-in
>> then we should be adding new functionality that is sensitive to the
>> state of the enumerable attribute.
>> 
>> Allen
> 
> Well, I had a real-world issue in which enumerability (and non-enumerability of methods) was still important.
> 
> In Amber, the Smalltalk implementation that compiles to JavaScript, there were issues[1], which failed with jQuery.ajax call. The object passed as options parameter was a HashedCollection, which mimicked JS object (keys as strings etc.), but the methods inherited via prototype striked back. JQuery read all properties (own as well as inherited), which makes sense, one can have templates and Object.create() from them, Object.defineProperty also honours inherited properties.
> 
> But some of the inherited properties make this fail or eat 100%CPU. Similar problem appeared with jQuery.css call (though I can't find an issue, it was probably only on the mailinglist).
> 
> The fix[2] was to make methods non-enumerable.
Interesting...

> 
> Now, jQuery takes enumerability (and I think not only jQuery does this) as a rough equivalent of "published" so it treats enumerables as visible part of object and non-enumerables are ignored for object-holding-some-data scenario.
> 
> If enumerable is to be deprecated, how should this be solved? If jQuery stops to honour inherited attributes, it would break Object.create()d data passed in. If not, one cannot safely pass in instance of the class with method, because methods will be included in the properties.

Neither the enumerable attribute or for-in is going away. So, as long as jQuery keeps using for-in the Amber fix will be fine.

The more interesting question is, in a future ES6 fully deployed world, what should jQuery use instead of for-in for the equivalent purpose and should the enumerable attribute have an effect upon it.  Should it use the keys(obj) iterator function (or the Dict(obj).keys idiom discussed at the last TC39.meeting)?  Should such "keys" functions/methods report non-enumerable properties?

Probably, the most important question concerns whether user defined methods (particularly in class definitions) should be enumerable.  The reason TC39 (rather abruptly) decided to switch from concise methods being non-enumerable to enumerable was because nobody had a full understanding for the full breadth of how the existing web depends upon enumerability. The jQuery usage is a good example.  The prevailing argument is that in ES<=5.1 all user defined properties are enumerable (except those defined using Object.defineProperty and friends), so the safest thing is to continue that tradition and make properties defined via concise methods enumerable.  For example,

replacing:

jquery.mixin({
   foo: funtion() {},
   bar: function() {}
});

with
jquery.mixin({
   foo() {},
   bar() {}
});
     
shouldn't break anything.

It's a bigger stretch, but the same logic applies to:

jquery.mixin(new class {
   foo() {},
   bar() {}
});

If anybody has a strong counter argument, now would be the time to make it.

Allen



> 
> Thanks, Herby
> 
> [1] https://github.com/NicolasPetton/amber/issues/217, https://github.com/NicolasPetton/amber/issues/88
> [2] https://github.com/NicolasPetton/amber/pull/202
> 



More information about the es-discuss mailing list