In JavaScript, I want to compare a value for (strict) equality to false.
From Java / C# I am used to writing:
if (!value)
//Do Something
However, I can not use it in JavaScript as null, undefined (and others IMHO) evaluate to false inside an if-statement, too. (I don't want that).
Thus, I have therefore been writing the following to formulate such a check:
if (value === false)
//Do Something
Yet, this construct looks a little bit strange to me.
Are there any more elegant ways here (which lead to the same results as the === false of course)?
Introducing a method isFalse would be an option, of course, but that's not what I am looking for as it would look even more distracting than the === false.
If you truly want to check for an explicit false value in Javascript, as opposed to a 'falsy' value (null, undefined, 0, etc.) then === false is by far the most standard way of doing so. I don't think it needs to be changed - that's part of the beauty of such a dynamic language!
Please, don't write a function isFalse() (a candidate for The Daily WTF), use the === operator even if it looks strange to you, there is no cleaner way.
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.)
Underscore.js has two methods _.isNull and _.isUndefined which we use a lot in our code and we've also created a mix-in for _.isUndefinedOrNull.
I recently realised that I could easily use javascripts "truthiness" to achieve the same results most of the time so the question is, is that considered bad practice?
What's better?
if(someVariable){...}
or
if(_.isNull(someVariable) || _.isUndefined(someVariable){...}
They both are entirely different.
if (someVariable)
will evaluate to falsy, if someVariable is 0 or false. So it is better to have explicit checks in this case. You might like to check the truth table in this answer which shows when a variable will be evaluated to either truthy or falsy.
I recently realised that I could easily use javascripts "truthiness" to achieve the same results most of the time
If only most of the time, then your solution doesn't work. Use if (someVariable == null) instead to test for either undefined or null.
so the question is, is that considered bad practice?
Not necessarily. If you know that all the possible values for someVariable other than the null/undefined you want to test for are truthy (e.g. objects), then it's fine.
If they can be primitive values, it's usually a mistake except your condition explicitly wants to test for the falsy values of the respective type. In your null-comparison case it would a mistake.
I see in some javascript codes that people write something like this:
var myVar = "true";
//...
if(myVar == "true") {
//...
}else{
//...
}
Why people don't use TRUE or FALSE? As far as I know boolean type is obvious for browsers.
Or is just a poor code ... and try to never write in this way.
It's just poor code. Try to never write in this way.
This kind of code is just horrible for maintainability. Both the == (instead of ===) and the true as string.
PS: besides, "true" == true // false. For the === argument, it's simply because true == 1 // true, and a lot of others look alike stuff like this.
You should not do this, unless you really expect a string that contains true for some reason :). But even in that case, using strict equality (===) would be the right choice.
In the code example you are showing, this is simply a terrible way of writing code.
It's just poor code, as you say.
A "real" developer never writes if (condition == true), but only if (condition)
Could also be written if (true == condition). This is called Yoda style and is designed to prevent unwanted assignment of variables if you mistakenly write = instead of ==.
I would like advice as to best practice in testing object existence for cross-browser compatibility.
There seem to be many ways of testing for object/function/attribute existence. I could use jquery or another library, but for now I want to stick as closely as possible to w3c rather than use what amounts to a whole new language.
What I'm trying to do
I'm trying to write a utility library that tries to stick to w3c methods so I can just call
xAddEventListener(elem, type, listener, useCapture)
for all browsers rather than
elem.AddEventListener(type, listener, useCapture)
just for w3c compliant browsers. If another library already does this, please let me know.
I saw this today:
if (typeof node.addEventListener == "function")
but will this ever yield a different result than plain
if (node.addEventListener)
Style documents?
A reference to a standards or styles document would also be useful. I've found https://developer.mozilla.org/en/Browser_Detection_and_Cross_Browser_Support
but that was last updated in 2003. It advocates simple
if (document.images)
tests for most existence tests and
if (typeof(window.innerHeight) == 'number')
only with numbers because if(0) would evaluate to false
Examples to inspire comment:
if (myObject)
Can an object or function ever fail this simple test?
if (myObject != undefined)
When is this better than the previous test?
if (typeof(myObject) == 'object')
This appears to be the original way of calling type of, but some people say that typeof is a keyword and not a function. Also, why not one of the simpler tests?
if ( typeof myObject.function !== undefined ) {
One post said to alway use === or !== as it differentiates between null and undefined. Is this ever important in practice?
Another possibility is:
try {
node.addEventListener(...)
}
catch(err) {
node.attachEvent(...)
}
Which in python appears to be becoming the favourite way of dealing with these type of things.
Using exceptions looks potentially much cleaner as you could write easy to understand w3c compliant code, and then deal with exceptions when they come.
Anyway, what do people think? Please can you list the pros and cons of methods you like/dislike, rather than simply advocating your favourite.
It all depends on how specific you want to be / how much you want to assert before calling a function.
if (myObject)
Can an object or function ever fail this simple test?
No, the only values that do not pass an if clause are false, 0, "", NaN, undefined and null. These are all primitives. Objects (including functions) will always pass an if clause.
if (myObject != undefined)
When is this better than the previous test?
If you want to check whether a value is "meaningful", i.e. not undefined or null. For example,
if(numberInputtedByUser) {
// do something with inputted number
}
will fail the if clause if the number is 0, while you probably want 0 to be allowed. In such case, != undefined is a slightly better check.
if (typeof(myObject) == 'object')
This appears to be the original way of calling type of, but some people say that typeof is a keyword and not a function. Also, why not one of the simpler tests?
It is a keyword. You can call it in a function-like fashion, though. In its most bare form you can use typeof like this:
typeof myObject
You can, however, add (extraneous) parens since they don't mean anything:
typeof (myObject)
Just like you can do:
(myObject).key
or even:
(((myObject))).key
And you can then remove the space after the typeof if you want, resulting in something that looks like a function call.
As to why to use typeof - you can be even more certain of the type of variable. With the if(...) test, the values that pass can be all kind of things - basically everything except the list I posted above. With if(... != undefined), you allow even more to be passed. With if(typeof ... == 'object'), you really only allow objects which might be necessary depending on what you're processing.
if ( typeof myObject.function !== undefined ) {
One post said to alway use === or !== as it differentiates between null and undefined. Is this ever important in practice?
=== is really preferred over ==. While differentiating between null and undefined is not always necessary, it is a very good practice to save yourself from the results of quirks like 0 == ''. If you want to check whether a number is 0, then === 0 is the way to go, since == 0 also allows for an empty string (which you might not expect and probably don't want). Even in cases == doesn't cause quirks, you'd be better off using === at all times for consistency and avoiding surprising bugs.
try {
node.addEventListener(...)
}
catch(err) {
node.attachEvent(...)
}
This is of course possible and very straight-forward. Note however that try catch is said to be slow. Moreover, you don't really account for why it fails. It's a bit simple-minded (but may work fine).
if (typeof node.addEventListener == "function")
but will this ever yield a different result than plain
if (node.addEventListener)
Yes, like I said above, the first only passes functions whilst the second allows anything except that list of "falsy" values. One could add Node.addEventListener = 123, and it will pass the if clause in the second case. But IE fails to give a correct typeof result:
typeof alert !== "function"
I bet the same goes for addEventListener so you'd still be avoiding that function even if it exists.
In the end, I would just use a simple if clause. Of course this will fail when you add weird things like Node.addEventListener = 123, but then again you're bound to expect weird things happen.