Coming from PHP I understand the difference in using == verses === in a comparison operation, but with JavaScript is it acceptable to use == or ===?
I wanted to validate my JavaScript code and found JSLint. While running the validation with JSLint I see these types of messages.
Some examples:
var show = $('input[name=female]:checked').val() == "true";
Problem at line 278 character 70: Expected '!==' and instead saw '!='.
and
var show = $('input[name=living]:checked').val() != "false";
Problem at line 283 character 38: Expected '!==' and instead saw '!='.
So My question is, Would using the current syntax of == or != be valid/correct or do I need to use === and !== ?
EDIT: Just to point out the code does work
It is correct in a way but JSLint expects strict comparison to prevent problems with type conversion.
It is good practice to always use strict comparison and "normal" comparison only where you really need/want it (because you want to make use of type conversion for some reason).
From JSLint's documentation:
== and !=
The == and != operators do type
coercion before comparing. This is bad
because it causes ' \t\r\n' == 0 to
be true. This can mask type errors.
If you only care that a value is
truthy or falsy, then use the short
form. Instead of
(foo != 0)
just say
(foo)
and instead of
(foo == 0)
say
(!foo)
Always use the === and !==
operators.
Crockford and JSLint are somewhat dogmatic on this point, and I think over-prescriptive. Always using === rather than == is a reasonable rule of thumb for inexperienced JavaScript developers, but if you know the basic rules then there is no problem with using ==. In particular, if the two operands are guaranteed to be of the same type (such as in a typeof comparison like typeof foo == "undefined") then the two operators are specified to follow precisely the same steps.
There is also a reasonable point about habitually using === removing the need to think about which operator to use, but frankly I prefer to be forced to consider all the possible values of the two operands I'm comparing and find JSLint unnecessarily nannying.
The == syntax is valid but in some cases it can lead to rather nasty bugs in large projects. If you don't have a good reason to use == you should by default write JavaScript with === because it checks for type as you know.
It works either way, but you will save yourself pain in the future if you default to ===.
Depends on the situation.
=== is often preferred because you won't have any false-positives that you might not have considered (it might also be slightly quicker in some implementations because it compares to less potential values, although I haven't checked that, just a thought, and the speed difference would be negligible).
== is often more convenient to cover many/all cases (if I'm not mistaken, jQuery doesn't pass JSLint because in some places the code intentionally uses == to cover a multitude of cases rather than testing each one individually).
you can do just == and !=, I don't think there would be any problems with that.
Related
Is it acceptable to use type coercion (== instead of ===) to check for undefined/null?
What are the downsides? Is there a better way to check for undefined/null?
Clarification: I am looking for a statement that will check for both undefined and null.
test(null);
test(undefined);
function test(myVar) {
if (myVar != undefined) {
alert('never gets called')
}
}
I'm going to attempt to address this question as objectively as possible, but it deals with some mushy "best practices" opinion stuff that can trigger people to forget that there's more than one way to do things.
Is it acceptable to use type coercion (== instead of ===) to check for undefined/null?
It's acceptable to write code however you see fit regardless of anyone who tells you otherwise. Including me.
That's not really helpful here, so let me expand on that a bit, and I'll let you decide how you feel about it.
Code is a tool that can be used to solve problems, and == is a tool within JavaScript code to solve a specific problem. It has a well-defined algorithm which it follows for checking a type of equality between two parameters.
===, on the other hand, is a different tool that solves a different, specific problem. It also has a well-defined algorithm which it follows for checking a type of equality between two parameters.
If one tool or the other is appropriate for your use-case, then you shouldn't hesitate to use the tool.
If you need a hammer, use a hammer.
But if all you have is a hammer, then everything looks like a nail, and this is the core issue with ==. Developers coming from other languages often aren't aware of how == works and use it when === would be appropriate.
In fact, most use cases are such that === should be preferred over ==, but as you've asked in your question: that's not true in this instance.
What are the downsides?
If you relax your standards for === and allow developers to use == you may very well get bitten by misuse of ==, which is why sticking religiously to === may be acceptable to some, and seem foolish to others.
if (val === null || val === undefined) {...
is not particularly difficult to write, and is very explicit about intent.
Alternatively,
if (val == null) {...
is much more concise, and not difficult to understand either.
Is there a better way to check for undefined/null?
"better" is subjective, but I'm going to say, "no" anyway because I'm not aware of any that improve the situation in any meaningful way.
At this point I will also note that there are other checks that could be performed instead of null/undefined. Truthy/falsey checks are common, but they are another tool used to solve yet another specific problem:
if (!val) {...
is much more concise than either of the previous options, however it comes with the baggage of swallowing other falsey values.
Additional notes on enforcement via linting:
If you follow the strictness of Crockford's JSLint, == is never tolerated, in the understanding that a tool that's "sometimes useful" but "mostly dangerous" isn't worth the risk.
ESLint, on the other hand, allows for a more liberal interpretation of the rule by providing an option to allow null as a specific exception.
== undefined and == null are both equivalent to checking if the value is either undefined or null, and nothing else.
As for "acceptable", it depends on who is looking at the code, and whether your linter is configured to ignore this special case.
I can tell you for sure that some minifiers already do this optimisation for you.
The ideal way to test for undefined is using typeof. Note you only need to test them separately if you care about a difference between undefined and null:
test(null);
test(undefined);
function test(myVar) {
if (typeof myVar === "undefined") {
// its undefined
}
if (myVar === null) {
// its null
}
}
If you don't care if its undefined/null, then just do:
test(null);
test(undefined);
function test(myVar) {
if (!myVar) {
// its undefined or null, dunno which, don't care!
}
}
There is a SonarQube JavaScript Rule (javascript:S2688) which says that the use of a === NaN is a bug because it's always false.
I agree with that but I think to use a !== a instead (this is suggested by SonarQube) is a very bad idea.
It's a funny JavaScript fact but certainly not a "best practice".
What about Number.isNaN(a)? Why is this not the suggested solution? Are there any differences or problems which I've missed?
the use of a === NaN is a bug because it's always false.
This behaviour is not a bug, because it is how NaN has been defined to work. But if you actually used a === NaN in a program then that would be a bug because of the always-false result.
a !== a instead ... is a very bad idea. It's a funny JavaScript fact but certainly not a "best practice".
I disagree with your "certainly". Due to problems with the original global isNaN() function (which I'll explain in a moment), a !== a was, historically the best way to test for NaN. So in fact it is a very common practice to use that technique, and I would expect the vast majority of experienced JavaScript developers to be familiar with it.
NaN is the only value that tests as not equal to itself.
What about isNaN(a)? Why is this not the suggested solution? Are there any differences or problems which I've missed?
The original, global isNaN() function doesn't actually test whether its argument is NaN. Nor does it test if its argument is some other non-numeric value. What it does is first try to convert its argument to a number and then test if the result of that conversion is equal to NaN. This implicit conversion means that, e.g., isNaN("test") returns true even though a string is not equal to the value NaN. And isNaN("") returns false because an empty string can be coerced to 0. If that behaviour is what you're looking for then yes, use isNaN().
So all of that is why ECMAScript 6/2015 introduced a new function, Number.isNaN(), which does test specifically for the value NaN, giving an equivalent result to the old-school a !== a.
As suggested in the comments, for older browsers (basically old IE) that don't support Number.isNaN(), if you want something clearer than a !== a and don't mind longer code you can do this:
typeof a == "number" && isNaN(a)
...which is one of the two Number.isNaN() polyfills suggested by MDN. (The other just uses a !== a.)
I have a timer object written in javascript and my goal is to make it as efficient and fast and thus as accurate as possible.
One of my concerns has to do with a specific case that could generally be applied to all manners of coding and I'm sure has been asked before, I just am not sure what terms to use when searching for it.
My question is which of these 2 cases is faster/more efficient?
Case 1: Assigning a variable some value in a repeated section of code, even when you know the value only needs to be assigned once.
Case 2: Checking the value of the variable, thus conditionally assigning it.
function runOnce(){
timer.someValue = { //some object...};
}
function someRepeatedFunction(){
timer.someValue = null;
//vs
if(timer.someValue){
timer.someValue = null;
}
}
Which of those cases would be faster?
Micro-optimization #1
If you insist on the conditional checking, I would bypass using the == operator (that I think Javascript uses automatically) and go for the === operator.
The identity === operator behaves identically to the equality == operator except no type conversion is done, and the types must be the same to be considered equal.The == operator will compare for equality after doing any necessary type conversions. The === operator will not do the conversion, so if two values are not the same type === will simply return false. It's this case where === will be faster, and may return a different result than ==. In all other cases performance will be the same.
Micro-optimization #2
With respect to the choice between the assignment & conditional checking, it seems logical to go for assignment in the case of using a global variable (like the one you seem to be using). Unless you plan on handling cases in an else situation there's no need to continually check what the current typeof the object or it's value is.
After reading through Lodash's code a bit and learning that it uses typeof comparisons more often than not (in its suite of _.is* tools), I ran some tests to confirm that it is faster, which it is, in fact (if marginally).
Discussing my confusion with a fellow developer, he pointed out that in case 1:
var a;
return a === undefined;
Two objects undergo comparison, whereas in case 2 (the faster case):
var a;
return typeof a === 'undefined';
is a far more simple and flat string compare.
I was always of the thought that undefined inhabited a static place in memory, and all triple equals was doing was comparing that reference. Who's correct (if either)?
JSPerf Test:
http://jsperf.com/testing-for-undefined-lodash
In this case (with var a in scope), both of the two posted pieces of code have identical semantics as x === undefined is only true when x is undefined and typeof x will only returned "undefined" when x is undefined (or not resolved in the execution context).
That out of the way, we end up with:
undefined === undefined
vs.
"undefined" === "undefined"
So, even in a naive implementation case the "difference" between the two is SameObject(a,b) vs StringEquals(a,b) as per the rules for Strict Equality Comparison.
But modern implementations of JavaScript are quite competitive and, as can be seen, are very well optimized for this case. I don't know of the exact implementation details, but there are at least two different techniques that could allow the performance (in FF/Chrome/Webkit) to be the same for both cases:
ECMAScript implementations may intern strings, such that there is only one "undefined" string. This would make the StringEquals(a,b) effectively the same as SameObject(a,b) which would end up amounting to a "pointer comparison" in the implementation - this alone could explain why the performance is the same.
Additionally, because typeof x === "undefined" is a common idiom, it could be translated during the parsing to end up in a special call that performs the same, say TypeOfUndefined(x). That is, the implementation could bypass the === (and StringEquals) entirely if it so chose.
IE comes out as a the "clear loser" and seems to be missing an applicable optimization here.
The implementation of the undefined value is outside the scope of ECMAScript; there are no mandates that it must be a single value/object in the implementation.
In practice, however, undefined (and other special values like null) is most likely implemented as either a singleton (e.g. "one object in memory") or as an immediate value or value flag (such that there is actually no undefined object).
According to EcmaScript (see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf ) if both expressions are strings (typeof returns a string) it perfroms a string comparison (char by char), otherwise it just compares references (in case when one of the sides is undefined). There is no way that string comparison would be more efficient then simple two numbers (i.e. addresses in memory) comparison. However it is possible that it is highly optimized (browsers do not follow EcmaScript in 100%) so it's really hard to say.
Proper benchmark:
http://jsperf.com/undefined-comparison-reference-vs-string
Note that in your test the initial value of a is undefined (may or may not matter, it seems that it does).
Conclusion: always use
return a === undefined;
It definitely won't be slower and it might be faster. Besides it seems more natural to compare something to a special undefined object rather then to a string.
Is there any difference (compiler/interpreter/juju wise, etc) between the two versions of checking the result of the typeof operator?
I am asking because I see the first version a lot of times, as if it followed a concept, while version two is way more readable and better describes my intention: primarily I am interested in the type of a variable and not a string being equal with something.
UPDATE:
while it's not part of the original question it worth noting that x == y is never a good practice when you are about to check equality. One should always use the === operator for that.
Update
There is no difference in terms of functionality but it seems that in JavaScript, you get an error in either way (which is good, thanks to JS):
Invalid left-hand side in assignment
So it seems to be just a habit of developers from other programming languages. For example in PHP if you did:
if ($var = 'foo')
PHP will silently assign foo as value to $var but with following:
if ('foo' = $var)
It will throw an error.
I am asking because I see the first version a lot of times
There is no difference in what they do. However first version will throw an error if you happen to write:
'value' = typeof X
Notice = instead of == or ===
This is generally good practice, people from other languages have habit of doing it that way in JavaScript also.
There will be no difference, as the equivalence operation will return the same thing, regardless of which way round it is.