views:

194

answers:

5

Throughout many third-party libraries and best practices blogs/recommendations, etc... it is common to see syntax like this:

typeof x === 'object' (instead of typeof x == 'object')
typeof y === 'string' (instead of typeof x == 'string')
typeof z === 'function' (instead of typeof x == 'function')

If the typeof operator already returns a string, what's the need to type check the return value as well? If typeof(typeof(x)) is always string, no matter what x actually is, then == should be sufficient and === unnecessary.

Under what circumstances will typeof not return a string literal? And even if there's some fringe case why is the additional type check being used for object, string, function, etc...

+8  A: 

To answer the main question - there is no danger in using typeof with ==. Below is the reason why you may want to use === anyway.


The recommendation from Crockford is that it's safer to use === in many circumstances, and that if you're going to use it in some circumstances it's better to be consistent and use it for everything.

The thinking is that you can either think about whether to use == or === every time you check for equality, or you can just get into the habit of always writing ===.

There's hardly ever a reason for using == over === - if you're comparing to true or false and you want coercion (for example you want 0 or '' to evaluate to false) then just use if(empty_str) rather than if(empty_str == false).


To those who don't understand the problems of == outside of the context of typeof, see this, from The Good Parts:

'' == '0'          // false
0 == ''            // true
0 == '0'           // true

false == 'false'   // false
false == '0'       // true

false == undefined // false
false == null      // false
null == undefined  // true

' \t\r\n ' == 0    // true
Skilldrick
No, that's not what I asked: I'm asking specifically when using the typeof operator.
Eric P
Shouldn't that be 'if(empty_str === false)' ;)
Gary Willoughby
@Eric I know, but what I'm saying is the reason to use `===` is for consistency with the rest of your code.
Skilldrick
Thanks. Seems to be the consensus so far - style over need.
Eric P
@Eric A lot of good coding practices are about style. That doesn't mean they're a waste of time.
Skilldrick
I agree with that 100%. But at the same time this style seems to be born out of mistrust of the implementation of the language.
Eric P
@Eric I think it's a perfectly grounded mistrust! The rules for type coercion are very weird.
Skilldrick
Sure, but in the case of typeof, where we're applying a built-in operator that is stated to return a value of a specific type, that's saying you don't trust the operator.
Eric P
@Eric I see that, but what I'm trying to get at is that it's easier to not have to say "in the case of", but to just go with `===`.
Skilldrick
Eh, I just type it as I know it, and the fact that there's an operator involved makes it an explicit case.
Eric P
@Eric Different strokes for different folks! It's perfectly justifiable for you to do it that way; my answer is saying why others often blanket-apply `===`.
Skilldrick
Sure. Thanks for your responses. I didn't expect anyone to jump on it so quick.
Eric P
+3  A: 

If the typeof operator already returns a string, what's the need to type check the return value as well? If typeof(typeof(x)) is always string, no matter what x actually is, then == should be sufficient and === unnecessary.

It's subjective. You can just as easily turn this around, and ask, "Why would you use == when you don't expect implicit conversions?" Both work fine here, so use the one you feel expresses your intention better. Try to be consistent within a project.

Matthew Flaschen
Thanks. Seems to be the consensus so far - style over need.
Eric P
A: 

Triple equal operators are mostly used for variable type and value checking (all in 1 expression), also known as equality without type coersion.

Example:

<script type="text/javascript">
    var a = 1;
    var b = 1;
    var c = "1";
    var d = "1";

    alert (a === b); //True, same value and same type (numeric)
    alert(c === d); //True, same value and same type (string)
    alert(b === c); //False, different type but same value of 1
</script>

See, Doug Crockford YUI Theater on Type coersion.


If the typeof operator already returns a string, what's the need to type check the return value as well? If typeof(typeof(x)) is always string, no matter what x actually is, then == should be sufficient and === unnecessary.

The most efficient reason for not using typeof and rather the === operator would be for type coersion (interpretation) between browsers. Some browsers can pass 6=="6" as true and some wouldn't (depending on the strictness of the JS interpreter) so by introducing type coersion would clarify this. Also, it would bring the "Object-Orientativity" approach to it since Javascript are not type-based variables (i.e. variable types are not declared on compile time like in java).

e.g. in java this would fail,

if ("6" instanceof Number) { //False

Hope I answered your question.

The Elite Gentleman
Again - not what I asked.
Eric P
Oops...sorry, never read your question fully...updating....
The Elite Gentleman
Nope, I'm asking specifically in cases involving the use of the typeof operator. typeof 6 should always return the string literal "number", so type checking "typeof 6" should never be necessary.
Eric P
well, typeof is dependent on how browser interpret the variable or value....so your typeof can work on one browser and fail on another (typical is the IE case). Most JS developers want a library that runs on all brothers with minimal knowledge of each browser. So, playing with the language fully without learning each browser tweeks, helps.
The Elite Gentleman
What's an example in IE where typeof does not return a string literal?
Eric P
@Gentleman: `typeof` is implemented consistently across browsers. Do you have an example of it working differently between browsers?
Tim Down
I agree that `typeof` is consistent across browsers. What I'm saying that doing `typeof` requires you to know the type (which doesn't guarantee that each types are valid to all browsers). That's what I'm trying to say.
The Elite Gentleman
I highly doubt there is any Javascript interpreter that would evaluate `6=="6"` as `false`
MooGoo
+1  A: 

There's no reason at all to favour === over == in this case, since both operands are guaranteed to be strings and both operators will therefore give the same result. Since == is one character fewer I would favour that.

Crockford's advice on this is to use === all the time, which is reasonable advice for a beginner but pointlessly paranoid if you know the issues (covered in other answers).

Tim Down
Thanks. Seems to be the consensus so far - style over need.
Eric P
+1  A: 

Because === is quicker than ==, due to omitting type coercion. Sure it is probably a negligible difference but it is still there.

Dmitri Farkov
This isn't necessarily true: if you look at the steps each operator is required to take in the ECMAScript spec, they are in fact identical in the case of comparing two objects of the same type such as two strings. Try benchmarking it.
Tim Down