开发者

Why should "current in mailArchive" be a condition for closure?

The code is 开发者_JAVA百科as follows

var mailArchive = {0: "Dear nephew, ... (mail number 1)",
                   1: "(mail number 2)",
                   2: "(mail number 3)"};

for (var current = 0; current in mailArchive; current++)
  print("Processing e-mail #", current, ": ", mailArchive[current]);

I would think current < mailArchive.length would be a better closure condition....

Does current in mailArchive accomplish the same thing, as it appears to in the interpreter (required for print function)? If not, what does it accomplish and how?


Yes, it works in the interpreter, I tested it with a node.js interactive session. mailArchive.length, however, will not work as mailArchive is an Object, not an Array, so doesn't have a property named length.

current in mailArchive checks whether the object mailArchive has a property with the name given in the variable current.

As you may or may not know, however, this approach is not usual for JavaScript. Much more common is to make mailArchive an array instead and use the usual condition current < mailArchive.length


What do you mean by "current < mailArchive.length would be a better closure condition"? Also, print function doesn't really require anything here. It just receives current and the value of the mailArchive[current] as parameters. It's also not a closure, just as a side note.

Regardless, "Eloquent JavaScript" author only tries to show that instead of using Objects in such an awkward way, there is a build in construct - Array. Which you will traverse using current < mailArchive.length.

As for what it accomplishes - in is an operator that checks whether the property (in this case value of current) belongs to the object (mailArchive here). Since the properties are named just like indexes ('0', '1', etc.) - it's intent is much like the normal

for (var current = 0; current < mailArchive.length; current++)

loop.

There are several problems with this, however. in operator searches for properties not only on the object itself, but on it's whole prototype chain. Which means that if that mailArchive object had a prototype defined for it - in operator would have parsed through the properties of the prototype as well. Not something you want in your loops, normally.

There are ways to overcome this. Normally hasOwnProperty method (defined on Object) is used to distinguish the properties that belong to the object itself.

The the for loop above can be rewritten like so:

for (var current in mailArchive)
{
   if( mailArchive.hasOwnProperty(current) )
   {
       print("Processing e-mail #", current, ": ", mailArchive[current]);
   }
}

but that is considered somewhat of a bad practice.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜