views:

72

answers:

2

What's the right way to check for equality between Strings in Javascript?

+8  A: 

always Until you fully understand the differences and implications of using the == and === operators, always using the === operator will save you from obscure (non-obvious) bugs and WTFs. The "regular" == operator can have very unexpected results due to the type-coercion internally, so using === is always the recommended approach.

For insight into this, and other "good vs. bad" parts of Javascript read up on Mr. Douglas Crockford and his work. There's a great Google Tech Talk where he summarizes lots of good info:

http://www.youtube.com/watch?v=hQVTIJBZook

STW
It's not necessary when you're sure both operands are string, e.g., when using `if (typeof foo == "string")`
Marcel Korpel
@Marcel -- you're correct, but it's much better to *always* use the `===` operator and never have to worry about the "am I really, totally, 100% certain that `==` will behave how I think it will?"
STW
There are certain cases where it will *always* be a string, making `===` and its (infinitesimal) performance impact unnecessary. One is `typeof`, which is guaranteed to return a string. Another case off the top of my head is when you are iterating over a set of keys in an object -- of course, it also matters what you're comparing it to. These are cases where you don't have to "think" because it's guaranteed. I think for a beginner, it's not a bad idea to use `===`, but if you're experienced and know the spec well, you can forgo using `===` without risk.
CD Sanchez
@Daniel -- I agree, updated to note that `===` is the safer of the two and should be used until the differences are fully understood
STW
And there are also cases where type coercion is a *good thing*. An example would be when comparing user input from some form element, which is always retrieved as a string, to a number. There are others. Treating `==` and type coercion as some kind of evil bug is bad practice I think.
MooGoo
@MooGoo - Personally, I'll take Douglas Crockford's advice to *never* use `==`. He's one of the foremost JS experts, understands the good-bad-ugly and nasty of JS, and is a primary force for the next version of JS.
STW
@STW – one example why Crockford is not the alpha and omega of JavaScript, is his advice not to use unary increment/decrement (`++`/`--`).
Marcel Korpel
And never use `++` or `--` or single line `if/else` statements or `continue` or the `new` operator or any other number of perfectly legitimate code practices that Crockford has deemed "harmful". And of course never *ever* even consider thinking about using `eval` or `with` even if their pitfalls are well understood. And have you seen the next version of JS? Stricter syntax and a handful of helper functions, some which have been floating around for years, is about all we get after all this time. The syntax has not evolved at all. If Crockford is behind this, then it has been a bad thing.
MooGoo
@MooGoo, @Marcel -- alright. feel better?
STW
Oh yes, but that's not dependent on Stack Overflow. But your corrections improve this answer, so +1.
Marcel Korpel
+2  A: 

If you know they are strings, then there's no need to check for type.

"a" == "b"

However, note that string objects will not be equal.

new String("a") == new String("a")

will return false.

Call the valueOf() method to convert it to a primitive for String objects,

new String("a").valueOf() == new String("a").valueOf()

will return true

Anurag
you mean `new String("a") == new String("a")` will return false? what about `new String("a") === new String("b")`?
JSS
thank for that JSS, two string objects will never be equal unless they are the same object regardless of the value.
Anurag
@JSS: Additionally, `new String("a") == "a"` is true (but wouldn't be with `===`), because the left hand side will be converted into a primitive string value.
Matthew Crumley
@JSS: `new String("a") == new String("a")`, `new String("a") === new String("b")`, `new String("a") === new String("a")` will all return `false`, since you're dealing with references to objects of the `String` class, not primitives of type `string`.
palswim