for (var key in myobj) must be accompanied with
if(Object.hasOwnProperty.call(myobj,key))
example:
for (var key in myobject) {
if(Object.hasOwnProperty.call(myobject,key)){
...
}
}
myobject.forEach(function(){...}) already does this.
more:
You could do : myobj.hasOwnProperty(key) But then if myobj is NULL it
will throw an error.
So you use the method hasOwnProperty from the prototype object.
and you call it with changing the this object of it to your object.
Object.hasOwnProperty.call(myobj,key)
Most of you probably know this, but sometimes I encounter modules that
don't do this.
And they do unexpected errors.
--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en
It will probably throw 1 or 2 lines before in the "for (...)".
If you're using an object as a hash you can avoid it. If you want to be
sure, I use this:
for (k in obj) {
if (!obj.hasOwnProperty(k)) continue;
..
}
Or if I can, I don't need to handle "this" references, I use .forEach.
---
Diogo R.
Requests for enlightenment:On Sun, Feb 12, 2012 at 7:42 PM, Shimon Doodkin <helpm...@gmail.com> wrote:
for (var key in myobj) must be accompanied with
if(Object.hasOwnProperty.call(myobj,key))
example:
for (var key in myobject) {
if(Object.hasOwnProperty.call(myobject,key)){
...
}
}
myobject.forEach(function(){...}) already does this.
more:
You could do : myobj.hasOwnProperty(key) But then if myobj is NULL it
will throw an error.Wouldn't it be more efficient to simply check if myobj is null before trying to iterate over it?
In similar vein, wouldn't it be better to not declare the var inside the for() in this instance?
Depends on how much control you have over all the code in your
environment. Things are somewhat better in Node land, but in browser
land, all it takes is some library you're using that augments
Object.prototype and you're hosed unless you protect your own
enumerations from such augmentation.
--
Martin Cooper
Unless nil suddendly has keys, it wouldn't go into loop anyway.
Personally I don't like forEach too much, since I cannot break from
it, when I decide the rest is uninteresting. Or even return from the
parents function. At least not without some
oh-so-clever-but-ugly-misuse of exceptions. Why they didn't make the
standard forEach in that returning false terminates the loop is beyond
me, or even designed javascript so you can do "named returns", that is
returning directly the closures parent, which only would work if the
closure is not exported out of the function anyway. But honestly this
is all off-topic to Node.js. To Node javascript comes with its quirks
as it is, and is no language design project.
function forEach(obj, callback, thisp) {
var keys = Object.keys(obj);
for (var i = 0, l = keys.length; i < l; i++) {
var key = keys[i];
if (callback.call(thisp, obj[key], key, obj) break;
}
}
Then to use this function, simply do:
forEach(obj, function (value, key) {
// do something
});
If you want to preserve your "this" value, just pass it in as an
argument after the callback. The built-in Array.prototype.forEach
works just like this. If you're comfortable changing
Object.prototype, then put this function there (moving the first
argument to `this`).
If you want to be able to break out of the loop, simply return true
from the callback.
For older browsers, Object.keys can be implemented simply as:
Object.keys = function (obj) {
var key, keys = [];
for (key in obj) {
if (!obj.hasOwnProperty) continue;
keys.push(key);
}
return keys;
};
Same with forEach. I had forgotten about Array.prototype.some().
If you want the short-circuit of some, use my code from above, but
call it "some" to avoid confusion.
But in the end its just taste/style and there is not "right" answer.
I keep reading things saying "Object.keys is much faster than
for..in", but in most tests I do (and in a bunch I find on
jsperf.com), that is the opposite of the case.
One very important thing to remember in benchmarks, especially
micro-benchmarks like this is that your loop is probably not your
bottleneck. It's good to be performance aware and responsible with
resources, but it's not the only design constraint in your program.
It can be in some cases, but not usually.
What probably matters a lot more is the different semantics. As Scott
explained so clearly, the two works differently. If I don't want
deleted keys to go away during my loop, I'll save a snapshot of the
old keys using Object.keys and loop over that. If I want a scope per
loop iteration I'll use forEach. Local variables are very handy for
closures, remember that normal for loops don't have their own scope
and share with the surrounding code. If you have a callback in your
loop that uses a variable from the loop body, you most likely want to
use forEach or something that creates a new scope for the loop
iteration. If you want to use block semantics and like `continue` and
`break` (which support named goto btw) then use normal for(;;) or
for..in loops.
If you want a snapshot of the keys before the loop, use Object.keys.
If you want to include properties in the prototype chain or want
deleted keys to not get iterated over, then use for..in.
A separate concern is if you want a scope per iteration. Both for..in
and Object.keys can be used with either loop method:
// for..in with block semantics
for (key in obj) {
if (!obj.hasOwnProperty(key)) continue; // optional if you don't
want to include enumerable prototype properties
// do something, break. or continue
}
// for..in with scope per iteration
for (key in obj) {
loop(key)
}
function loop(key) {
setTimeout(function () {
// `key` is still the key from this iteration!
}, 100);
}
// Object keys with block semantics
var keys = Object.keys(obj);
for (var i = 0, l = keys.length; i < l; i++) {
var key = keys[i];
// do something with key, continue or break
}
// Object.keys with scope per loop
Object.keys(obj).forEach(function (key) {
setTimeout(function () {
// key is the one from this iteration, not the last key
}, 100)
});
These aren't the best ways to implement these various loops, they
merely show that with a good understanding of the language about any
kind of loop can be figured out.
In node I find it very useful to have a scope per iteration since I
often make async calls in my loop (parallel work ftw!) and with block
level loops the iteration variable changes to the last item in the
loop before the callback ever fires leading to nasty bugs.
But sometimes I'm writing a synchronous parser or compiler and block
tools are much more useful in that case (switches inside switches
inside for(;;) with continue and break all over the place)
Sorry for derailing the list with performance implications that seems
to have changed a little in the last year.
Happy coding everyone!
-Tim Caswell
2012/2/14 Scott González <scott.g...@gmail.com>:
I remember the older days of JS, where JS-engines were so slow,
anything you could possible offload to native code was a gazillion
times faster, even if it would be ridiculously more complicated done
there. I used to write some calculations by changing them to string
and doing some crazy regexps, since regexp engine was way faster than
JS. Or I daresay the most efficient way for deep cloning was
JSON.parse(JSON.stringify(obj)); Likely, not so today. Or before the
V8 came around with its hidden classes, some design decissions where
more taste than performance to cater for them.
Overall, albeit I'd like to have a good link for V8 optimizations,
tons of micro-optimizations hardly make you happy nor improve your app
significantly, most profiles I ran on projects on mine, the first
result was quite a surprise to me where 80% of the time is actually
burned.