On Nov 8, 2011, at 2:03 PM, Quildreen Motta wrote:

> On 08/11/11 18:49, Brendan Eich wrote:
>> 
>> The recommended practice when writing for-in loops in JS today is to write:
>> 
>>   for (i in o) {
>>     if (o.hasOwnProperty(i)) {
>>       body
>>     }
>>   }
>> 
>> Although many JS developers do not follow the recommendation (out of 
>> ignorance or intentionally, doesn't matter).
>> 
>> Should ES.next provide sugar for the recommended pattern? To make it compose 
>> with declarations and destructuring in the for head, it should use a 
>> contextual keyword immediately after 'for':
>> 
>>   for own (i in o) {
>>     body
>>   }
>> 
>> This is a small thing but it might pay off in the long run.
> Isn't that just:
> 
> Object.keys(o).forEach(function(i){ body })

Good grief. Your "just" is pointing the wrong way. The longer, more contingent 
in terms of mutable global and Object property bindings, form is not the 
primitive one.


> Iirc, that's faster than a for..in loop with filter in v8 due to the 
> aggressive function inlining, not sure about SpiderMonkey.

It's not necessarily faster or slower, implementations vary. And what is the 
length of the necessarily-reified, returned keys array? Have you tested large 
objects?

You can use it if you like (performance is not usually overriding).


> It also reads better and it's more composable -- for me, at least.

YMMV.

Again, ES.next already will support

  for (let i in keys(o)) {
    body
  }

if you have keys imported. There is no "there must be only one way to say 
things in JS" dogma in JS; this is a feature.


> I do use keep `var keys = Object.keys' and other hand aliases though.
> 
> It still seems to me it's overkill to add special syntax (and a new reserved 
> word, yuck!)

No new unconditionally reserved word. Rather, contextually reserved after 
'for', no impact on other uses of 'own'. ECMA-357 (E4X) did likewise with 'for 
each(... in ...)'.

Overkill may be writing a function around one's code just to call an array 
extra on a reified array of keys. Iterators can be much faster.

Here's another, more real-world concern: wrapping //body// in function (){...} 
breaks the principle of equivalence (TCP) and people can and do fail to capture 
the outer |this|, e.g. by var self = this, and propagate it to the revised 
//body// as self. Tom Van Cutsem had such a bug, Mark Miller has seen such 
bugs. They are serious runtime type/instance confusion bugs, possibly with 
security implications.

(Block-lambdas would help here, shameless plug -- but let's stay on target.)


> to something that isn't really worth it, given the Object API already 
> provides those methods.

for-in loops are quite commonly used. Object.keys is new and while people 
polyfill it, practice varies wildly.


> Also, are Object.values and Object.items standardised in ES.next. They're 
> quite useful?

They are *not* object methods, and you're mistaking Object.keys for the "@iter" 
module's keys function.

Returning iterators instead of eager arrays is a serious perf win for large 
objects.

/be


> 
>> 
>> /be
>> 
>> 
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to