This might be an “opportunity for optimization” … if not already discovered by someone else that is. First published on: Jul 19, 2009.
Consider the code bellow. Which one you prefer and why :
1.
1 |
if ( "m" in obj ) obj["m"]() ; |
2.
1 |
if ( "undefined" != typeof obj.m) obj.m() ; |
3.
1 |
if (obj.m) obj.m() ; |
3 seemed as an obvious winner, but then I gave it some thought, and …. I still have no easy answer to this one … 1 or 3 ?
Update 2010-02-11
Well, now, and after all the useful comments bellow, it seems to me the “best” solution might be this :
1 |
if ( "undefined" !== typeof obj && "function" === typeof obj.m ) obj.m() ; |
Of course now we have to decide what we do in the else part, of the above if() :)
6 thoughts on “JavaScript : The humble ‘in’ operator”
@Douglass
Thanks for a short but usefull discussion. 5. is a good code, provided ‘typeof’ operator is implemented as it should be. On each and every browser under each relevant OS. That is: I am slightly concerned about the portability of the case 5.
Now it will be very useful and even more interesting (than usefull) to see how each of these cases do perform in different browsers. Which is the fastest code?
After this experiment is done and we have clear results, we might ask ECMA committee, to remove use of the ‘in’ operator, as used here in the case 1.
I think you’d get more answers on comp.lang.javascript, but I guess the first is about as the same speed as the third, some profiling might help deciding, though these must take less than microsecond.
There is also
4.
if (obj.m === undefined) {
obj.m();
}
which I like better than 2.
The difference between 1 and 4 is that 1 distinguishes between the cases where m is missing and where m has the value of undefined. I think it is madness to allow the use of the missing as a value, but the language allows it. As far as I can tell, this is the only case where in is useful.
But what you really want here is
5.
if (typeof obj.m === 'function') {
obj.m();
}
So 5 is best. Then 3 because it rejects all of the falsy values so it is wrong less often. Then 4, then 2. And 1 is clearly the worst.
I do find it somewhat funny that here you are, writing about JavaScript, despite posting a comment on another blog that you don’t understand why anyone reads it because it’s about JavaScript…
@Jani
Thanks for your comment. I have posted a comment on “another blog” wondering why is it so popular when it shows, mainly, non interesting and already, elsewhere very mutch discussed points. Therefore, to me, it looks irrelevant. Also the blog owner/author sometimes gets plainly wrong about javascript and its idioms.
Ok, I realise that is well presented blog with well researched material, by someone who is not perhaps on your level , but certainly will be in time. Therefore “that” blog has followers because it is just plain “interesting” for them. And it is an achievement to make it interesting.
It appears irrelevant to me, but not to others who are beginning javascript.
My blog perhaps contains some advanced javascript and important points, but it is somewhat self-sufficient. As a such it is followed by few “chosen ones” only … unfortunately.
these 5 cases are all different, you cannot compare them. case 1, obj suppose to be an object with an “m” property which does not mean it is a function. Case 2, obj suppose to be an object (no primitives a la string, boolean, number) and the typeof property m is not undefined but it could be present, which does not mean it is a function. case 3, obj is an object and m is a property different from undefined, null, empty string, false, or 0 … which does not mean you can call m.
case 4 is about strictly undefined, which does not mean m is a function. finally, case 5, we assume obj is an object different from primitives and it has a proerty m which is a function … yeah, call it!
What does it mean?
Before we ask a core language to remove some feature we should understand if what we are trying to do make sense for our purpose. m in obj should be there, specially for compatibility reason where hasOwnProperty could return false but prop in obj true, letting us unterestand that was a prototype inherited property and not a setted one. Regards