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.
精彩评论