Implementing isNil - javascript

I am implementing a seemingly trivial utility function to check if a value is null or undefined.
My original implementation looked like this:
function isNil(value) {
return value === null || value === undefined;
}
I then looked up Lodash's implementation:
function isNil(value) {
return value == null
}
On the surface, this would seem like a naiive approach since it violates eslint's eqeqeq rule as well as only checking for null.
I'm guessing that this approach works due to a combination of JavaScript's truthiness and equality rules, but is there actually an advantage to Lodash's implementation?

value === null || value === undefined and value == null are equivalent as can be seen in the specification of the Abstract Equality Comparison Algorithm:
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
[...]
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
The "eqeqeq" rule of ESLint is not relevent as it is just for linting, it does not enforce anything in ECMAScript itself. And lodash does not use that rule.
Technically, there is no real advantage as it has the exact same outcome. One might argue value == null could be faster as it does only do one equality check and does not perform up to two calls of the Strict Equality Comparison Algorithm like your first example. It does most probably not matter at all as even if there was a difference, it would be very small.
Personally, I would use the value === null || value === undefined as it is clearer and does not even need a documentation. Besides, tools like uglify could easily replace value === null || value === undefined with value == null for production.

The two expressions seem to be functionally equivalent (source). Thus lodash's implementation would be preferable just because it requires slightly fewer comparisons.

Related

What's the common way to check if a field is null or undefined (but not zero or empty string) in Javascript? [duplicate]

Although there are semantic differences between JavaScript's null and undefined, many times they can be treated as the same. What's the preferable way of checking if the value is either null or undefined?
Right now I'm doing the following:
if (typeof value === "undefined" || value === null) {
// do something
}
Which is pretty verbose. I could, of course, create a function for this and import everywhere, but I'm wishing that there's a better way to achieve this.
Also, I know that
if (value == null) {
}
Will get the job done 90% of the time, unless value is zero... or false... or a number of implicit things that can cause obscure bugs.
Also, I know that
if (value == null) {
}
Will get the job done 90% of the time, unless value is zero... or false... or a number of implicit things that can cause obscure bugs.
No, it gets the job done 100% of the time. The only values that are == null are null and undefined. 0 == null is false. "" == undefined is false. false == null is false. Etc. You're confusing == null with falsiness, which is a very different thing.
That's not to say, though, that it's a good idea to write code expecting everyone to know that. You have a perfectly good, clear check in the code you're already using. Whether you choose to write value == null or the explicit one you're currently using (or if (value === undefined || value === null)) is a matter of style and in-house convention. But value == null does do what you've asked: Checks that value is null or undefined.
The details of == are here: Abstract Equality Comparison.
underscore js has a function for this _.isUndefined()
from https://underscorejs.org/#isUndefined
isUndefined _.isUndefined(value)
Returns true if value is undefined.
example:
_.isUndefined(window.missingVariable);
=> true
lodash has a similar function. see https://lodash.com/docs/4.17.11#isUndefined
Both have similar functions for isNull too.
I find the functions are useful for others to know what is being tested for.

Javascript: Which way is better to check conditional statement?

In javascript, which will be better way to check conditional statement in terms of performance, robustness and which is the best practice?
var x = null;
// this condition is checked frequently and x will be set to null or some value accordingly
if(x !== null){...}
OR
if(!!x){...}
You could just do
if (x) { ... }
Simply says, if x is a truthy value.
As Nina pointed out. I would always add some extra validation, depending on what I'm expecting.
if (x && x > 0) { ... }
Or
if (x && x instanceof Array)
But I'm always checking x has some sort of value and isn't undefined or null
It's never necessary to write if(!!x){...}. That is exactly the same thing as writing if(x){...}. Using the ! operator twice converts a value to a boolean that reflects whether it is "truthy" or not. But the if statement does that anyway: it tests whether the value you provide is "truthy". So whether you use !! or not it will do the same thing.
if(x !== null){...} is something else entirely. It doesn't just check whether x is "truthy", it specifically compares the value of x with null. For example, if x has the numeric value 0, if(x){...} or if(!!x){...} will not execute the ... code, because 0 is a "falsy" value, but if(x!==null) will execute the ... code, because 0 is not the same value as null.
A related example is if(x!=null){...} or if(x==null){...}. (Note the use of != or == instead of !== or ===.) This is a bit of a special case in JavaScript. When you compare against null using the != or == operator, it actually compares against either null or undefined and treats those two values the same. In other words, if x is either null or undefined, then if(x==null){...} will execute the ... code, but if(x!=null){...} will not execute the ... code.
It's generally recommended to avoid the == and != operators and use the strict comparison === or !== instead, but treating null and undefined the same can be useful in some situations, so this is a case where the non-strict operators are helpful.
In any case, the real question to ask is what is the purpose of your code, and what specifically do you need to test for here?
Assuming you need to check for a value which is strict inequality !== to null
this condition is checked frequently and x will be set to null or some value accordingly
if (x !== null) { /* */ }
Then you can only use the above comparison. Any other comparison would return a wrong result.
For example
var x = 0;
if (x !== null) { // true
console.log(x + ' !== null');
}
if (x) { // false
console.log(x);
}
// some more checks
console.log(undefined !== null); // true
console.log(undefined != null); // false
Edit: My response was quite wrong which I learned after my conversation with Nina Scholz in her own response to this thread. I updated accordingly.
There are many ways to check values depending on the type you expect to use. Therefore the problem is not so much about performance as it is with correct evaluation. Starting with your examples:
if(x != null)
This will evaluate to false if the value of x is either null or `undefined'.
The next case:
if(!!x)
This is an entirely different operation. It casts the value of x as a boolean, and in most cases if(x) will work the same way. But now, if the value is falsy, like 0, the empty string, the expression returns false. So, if expecting a number, you should check for the zero value:
if(x || (0 === x))
Bear in mind that if x were anything other than an int, the expression returns true.
And the case where you expect a string:
if(x || ('' === x))
Same thing here, if x was, say 12, the expression returns true.
I could go on with lots of examples. Unfortunately there are certain expressions that work in unexpected ways. For instance, it should be easy to check if a value is a number by calling isNaN(number), but if the value is an empty string or a representation of an array index ('2'), isNaN returns false.
I recommend you to check this table with all the type conversions so that you become more aware on how to check the validity of a value.

Is JavaScript identity compare really needed here?

This is from Crockford's JavaScript: The Good Parts
var is_array = function (value) {
return Object.prototype.toString.apply(value) === '[object Array]';
};
Would this code have worked just as well if he had used a simple equality compare == instead of the identity compare ===?
My understanding of identity is that it allows you to check if a value is really set to something specific, and not just something equivalent. For example:
x == true
Will evaluate to true if x is 1, or true, but
x === true will only be true if x is true.
Is it ever possible for the is_array function above to work with either == or ===, but not the other?
In this particular case == and === will work identically.
There would be no real difference in this case because both sides of the quality test are already strings so the extra type conversion that == could do won't come into play here. Since there's never any type conversion here, then == and === will generate the same result.
In my own personal opinion, I tend to use === unless I explicitly want to allow type conversion as I think there is less likelihood of getting surprised by some result.
You are correct. With == instead of === it should work fine.
=== is a strict match, and will not return true for 'falsy' or 'truthy' values (see this for more details). Which shouldn't apply in this situation.

Speed of comparing to null vs undefined in JavaScript

I have just run a very simple JavaScript performance test (don't ask why). The test declares a variable, but doesn't assign anything to it:
var x;
It then compares the speed of comparing the value variable to null, and to undefined, in other words:
var y = (x == null); and var y = (x == undefined);.
I was expecting the comparison with undefined to be the fasted. In fact it was nowhere near. The comparison with null was far and away the fastest, around 80% faster.
The results I've described above come from running the tests in Chrome (version 13). Running them in Firefox produces results far closer to what I would have expected (the comparison with undefined is faster than with null, albeit very marginally).
So, my question is what could the cause of this be? Why does Chrome seem to favour the comparison with null so greatly?
For quick reference, here's a screenshot of the results:
null is a reserved keyword which cannot be overriden, so when you are doing a comparison against null, all you have to do is a single comparison.
However, when you are checking against undefined, the engine must do a type lookup and then a comparison, meaning that it is actually slightly more demanding.
If you need to actually check to see if something is undefined, you should use
if(typeof notSet == "undefined"){ }
Proof
Try it... and set something to null in your JavaScript console.
null = "will error";
// Errors with --> ReferenceError: invalid assignment left-hand side
However, if you try and do it with undefined, it won't error. That is not to say that you can override undefined, because you can't, but that undefined is its own primitive type.
The only real similarity between null and undefined, is that they can both be coerced into a boolean false.
if i think well, they are not the same. so you can't use null instead of undefined.
typeof !== "undefined" vs. != null
You're comparing against the lookup of a variable called undefined (which returns an undefined value), so it's not doing what you were intending.
There are ways to check whether a variable is undefined. As the other posters have mentioned, typeof x === 'undefined' is one. (There's probably another possibility that is something like hasOwnProperty('x') executed on the global object, but that doesn't check the scope chain.)
I recently discovered that this:
if (typeof this._minLat === 'undefined') {
this._minLat = Math.min(...this.points.map(point => point.lat));
}
return this._minLat;
seems to be many times faster than this:
return this._minLat || Math.min(...this.points.map(point => point.lat));

JSLint Expected '===' and instead saw '=='

Recently I was running some of my code through JSLint when I came up with this error. The thing I think is funny about this error though is that it automatically assumes that all == should be ===.
Does that really make any sense? I could see a lot of instances that you would not want to compare type, and I am worried that this could actually cause problems.
The word "Expected" would imply that this should be done EVERY time.....That is what does not make sense to me.
IMO, blindly using ===, without trying to understand how type conversion works doesn't make much sense.
The primary fear about the Equals operator == is that the comparison rules depending on the types compared can make the operator non-transitive, for example, if:
A == B AND
B == C
Doesn't really guarantees that:
A == C
For example:
'0' == 0; // true
0 == ''; // true
'0' == ''; // false
The Strict Equals operator === is not really necessary when you compare values of the same type, the most common example:
if (typeof foo == "function") {
//..
}
We compare the result of the typeof operator, which is always a string, with a string literal...
Or when you know the type coercion rules, for example, check if something is null or undefinedsomething:
if (foo == null) {
// foo is null or undefined
}
// Vs. the following non-sense version:
if (foo === null || typeof foo === "undefined") {
// foo is null or undefined
}
JSLint is inherently more defensive than the Javascript syntax allows for.
From the JSLint documentation:
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.
When comparing to any of the following values, use the === or !== operators (which do not do type coercion): 0 '' undefined null false true
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)
The === and !== operators are preferred.
Keep in mind that JSLint enforces one persons idea of what good JavaScript should be. You still have to use common sense when implementing the changes it suggests.
In general, comparing type and value will make your code safer (you will not run into the unexpected behavior when type conversion doesn't do what you think it should).
Triple-equal is different to double-equal because in addition to checking whether the two sides are the same value, triple-equal also checks that they are the same data type.
So ("4" == 4) is true, whereas ("4" === 4) is false.
Triple-equal also runs slightly quicker, because JavaScript doesn't have to waste time doing any type conversions prior to giving you the answer.
JSLint is deliberately aimed at making your JavaScript code as strict as possible, with the aim of reducing obscure bugs. It highlights this sort of thing to try to get you to code in a way that forces you to respect data types.
But the good thing about JSLint is that it is just a guide. As they say on the site, it will hurt your feelings, even if you're a very good JavaScript programmer. But you shouldn't feel obliged to follow its advice. If you've read what it has to say and you understand it, but you are sure your code isn't going to break, then there's no compulsion on you to change anything.
You can even tell JSLint to ignore categories of checks if you don't want to be bombarded with warnings that you're not going to do anything about.
A quote from http://javascript.crockford.com/code.html:
=== and !== Operators.
It is almost always better to use the
=== and !== operators. The == and != operators do type coercion. In
particular, do not use == to compare
against falsy values.
JSLint is very strict, their 'webjslint.js' does not even pass their own validation.
If you want to test for falsyness. JSLint does not allow
if (foo == null)
but does allow
if (!foo)
To help explain this question and also explain why NetBeans (from) 7.3 has started showing this warning this is an extract from the response on the NetBeans bug tracker when someone reported this as a bug:
It is good practice to use === rather than == in JavaScript.
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. JSLint cannot
reliably determine if == is being used correctly, so it is best to not use ==
and != at all and to always use the more reliable === and !== operators
instead.
Reference
Well it can't really cause problems, it's just giving you advice. Take it or leave it. That said, I'm not sure how clever it is. There may well be contexts in which it doesn't present it as an issue.
You can add this to the previous line to disable these warning.
// eslint-disable-next-line

Categories