How do === and == handle null comparisons differently? - javascript

I have a simple json parsed object that sometimes has a variable tt defined and sometimes doesn't.
For some reason jsonobject.tt == null returns correctly 1 or 0 based on whether tt is defined. jasonobject.tt === null just returns 0 regardless. I thought === was the thing to use to avoid issues.
What's going on here?

=== is the strict equality operator, it compares type as well as value. The value null is the Null Type that has exactly one value - null.
Undefined is the Undefined Type, which also has only one value - 'undefined'.
When using the strict equality operator, null !== undefined because they are different types (see step 1 of the Strict Equality Comparison Algorithm, ECMA-262 § 11.9.6).
== is the equality operator. Comparisons using == use the Abstract Equality Comparison Algorithm (ECMA-262 § 11.9.3), which includes:
If Type(x) is the same as Type(y), then ...
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
So null == undefined returns true by definition. Strictly, testing for the presence of a property (regardless of its value), should use hasOwnProperty:
if (jsonobject.hasOwnProperty('tt')) {
// property exists
}
however in practice there isn't much difference to a strict test for undefined:
if (jsonobject.tt === undefined)
because whether the property exists and has a value of undefined or hasn't been defined at all is usually equivalent. Using === also means that the above will return false if tt exists but has been assigned a value of null.

For some reason (jsonobject.tt == null) returns correctly 1 or 0
Firstly a comparison returns true or false
Secondly you want
jsonobject.tt === undefined
If a value does not exist it is undefined.
Other detection methods are
!jsonobject.hasOwnProperty("tt");
or
!("tt" in jsonobject)
As a side effect of == being a totally weird operator, null == undefined. Thus jsonobject.tt == null will return true if the property is not there

If a variable hasn't been defined it has a value of undefined.
undefined == null
whereas
undefined !== null

Related

Type casting when == used instead of === [duplicate]

This question already has answers here:
Which equals operator (== vs ===) should be used in JavaScript comparisons?
(48 answers)
Closed 8 years ago.
I generally don't prefer using == but today i was just experimenting with the following code including == and the results are a bit confusing to me. Can someone please explain what is happening?
All these are falsy values:
'', 0, false, undefined, null
Suppose i did:
if (undefined == null) {
alert('a');
} else {
alert('b');
}
The statements below give true:
null == undefined
0 == ''
false == ''
0 == false
But why does the code below return false?
undefined == 0
undefined == ''
null == 0
Because 0, false and '' are "values" while null is "absence of value" and undefined is "absence of definition".
Thus, you can compare "values" with each other, same for "non-values". But you can't compare "values" with "non-values".
null and undefined are nothingness. i.e.
var a;
var b = null;
Here a and b do not have values. Whereas: 0,false and '' are all values.One thing common beween all these are that they are all falsy values, which means they all satisfy falsy conditions.
So, the 0,false and '' together form a sub-group.
On the other hand, null & undefined form the second sub-group. Check the comparisons in below image. null and undefined would equal. the other three would equal to each other. But, they all are treated as falsy conditions in JS.
This is same as any object(like {},arrays etc.), non-empty string & Boolean true are all truthy conditions. But, they are all not equal.
The == operator does not just check whether things are falsy; it follows a procedure called the The Abstract Equality Comparison Algorithm, which can be seen here: ECMAScript spec.
undefined == 0 and undefined == '':
According to the spec, undefined only compares true with undefined or null. Since neither 0 or '' are either of those values, it returns false.
null == 0
According to the spec, null only compares true with another null or with undefined - neither is the case here.
Use ===
It is generally better to use === and make the comparison you actually intend, rather than trusting to the == algorithm, and is generally faster too. It is easy to be caught out, as you have seen, when the algorithm does not do what you are expecting, and it is generally simpler to be explicit than to keep track of which path the comparison algorithm will take.
For general information on 'sameness' in javascript, see this MDN page.
But why does below gives false?
undefined == 0
undefined == ''
null == 0
The technical “Why” is because the Truth Table says this.
The philosophical “why” is because undefined and null are not a number and are not a string.
(parseInt(undefined) -> NaN).
So NaN != 0.
But careful: also undefined != NaN because NaN != NaN. Simply because a Banana is not a Kiwi. But Also Apple is not a Kiwi. And still Banana is not an Apple.
So the answer of avetisk is correct. You cannot compare object that you know what DON'T they are, but you don't know what they are.

Why does "undefined equals false" return false?

When I compare undefined and null against Boolean false, the statement returns false:
undefined == false;
null == false;
It return false. Why?
With the original answer pointing to the spec being deleted, I'd like to provide a link and short excerpt from the spec here.
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
The ECMA spec doc lists the reason that undefined == false returns false. Although it does not directly say why this is so, the most important part in answering this question lies in this sentence:
The comparison x == y, where x and y are values, produces true or false.
If we look up the definition for null, we find something like this:
NULL or nil means "no value" or "not applicable".
In Javascript, undefined is treated the same way. It is without any value. However, false does have a value. It is telling us that something is not so. Whereas undefined and null are not supposed to be giving any value to us. Likewise, there is nothing it can convert to for its abstract equality comparison therefore the result would always be false. It is also why null == undefined returns true (They are both without any value). It should be noted though that null === undefined returns false because of their different types. (Use typeof(null) and typeof(undefined) in a console to check it out)
What I'm curious of though, is that comparing NaN with anything at all will always return false. Even when comparing it to itself. [NaN == NaN returns false]
Also, another odd piece of information: [typeof NaN returns "number"]
Strict Equality
If possible, you should avoid using the == operator to compare two values. Instead use === to truly see if two values are equal to each other. == gives the illusion that two values really are exactly equal when they may not be by using coercion. Examples:
5 == "5" is true
5 === "5" is false
"" == false is true
"" === false is false
0 == false is true
0 === false is false
From the incomparable MDN, sponsored by the company of JavaScript's creator.
JavaScript provides three different value-comparison operations:
strict equality (or "triple equals" or "identity") using ===,
loose equality ("double equals") using ==,
and Object.is (new in ECMAScript > 6).
The choice of which operation to use depends on what sort of
comparison you are looking to perform.
Briefly, double equals will perform a type conversion when comparing
two things; triple equals
will do the same comparison without type conversion (by simply always
returning false if the types differ); and Object.is will behave the
same way as triple equals, but with special handling for NaN and -0
and +0 so that the last two are not said to be the same, while
Object.is(NaN, NaN) will be true. (Comparing NaN with NaN
ordinarily—i.e., using either double equals or triple equals—evaluates
to false, because IEEE 754 says so.) Do note that the distinction
between these all have to do with their handling of primitives; none
of them compares whether the parameters are conceptually similar in
structure. For any non-primitive objects x and y which have the same
structure but are distinct objects themselves, all of the above forms
will evaluate to false.
For a visual overview of the whole picture of equality in JavaScript:
https://dorey.github.io/JavaScript-Equality-Table/
The truth is, this seemingly "bad" aspect of JavaScript is a source of power when you understand how it works.
So undefined really means undefined. Not False, not True, not 0, not empty string. So when you compare undefined to anything, the result is always false, it is not equal to that.
You question is half, as we compare undefined/ null to any other types.
we will have false return.
There is no coercion happening, even we are using == operator.
This is so because it is so. :)
Read the ECMA standards here: https://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
Undefined is not the same thing as false, false is a boolean object (which has a value of 0 therefore it is indeed defined).
An example:
var my_var;
var defined = (my_var === undefined)
alert(defined); //prints true. It is true that my_var is undefined
my_var = 22;
defined = (my_var === undefined)
alert(defined); //prints false. my_var is now defined
defined = (false === undefined)
alert(defined); //prints false, false is defined
defined = (true === undefined)
alert(defined); //prints false, true is defined
According to the specification flow:
If Type(y) is Boolean, return the result of the comparison x ==
ToNumber(y).
1) undefined == false; -> undefined == Number(false); -> undefined == 0;
2) null == false; -> null == Number(false); -> null == 0;
There is no rule for these cases, so go with the behavior in the last step:
Return false.

JavaScript undefined replaced with null

In JavaScript undefined can be reassigned, so it is often advised to create a self executing function that assures undefined is actually undefined. As an alternative null and undefined are definitely == but are any other values loosely equivalent to null/undefined?
TLDR
Basically can you safely replace this:
(function(undefined){
window.f = function(obj){
if(obj===undefined || obj===null ){
alert('value is undefined or null');
}
}
})();
with:
window.f = function(obj){
if(obj==null){
alert('value is undefined or null');
}
}
If the above is 100% safe, why doesn't the JavaScript community/libraries drop undefined altogether and use the shorter x == null conditional to check for both null/undefined at once?
EDIT:
I have never seen someone actually represent an "unknown value" with 'undefined' vs null? I have never seen this scenario, and is why I originally asked the question. It just appears to be two incredibly confused values that are never used in their original intent. Standardizing everything to do a comparison obj==null would be beneficial for size and avoid any issues with reassignment. Everything would continue to work
var obj={};
obj.nonExistantProperty==null // true
var x;
ix==null // true
function(obj){
obj==null // true
}
The one exception to this rule appears to be when casting undefined/null to an integer. This is a pretty age case scenario, but definitely should be noted.
+(null)==0
while
isNaN(+undefined)
Considering NaN is the only value in JavaScript not equal to itself, you can do some pretty crazy things like:
+undefined == +undefined // false
+null == +null // true
Using null as a loose equality == drop in replacement for undefined is safe, provided you don't plan to cast the value to an integer. Which is a pretty edge case scenario.
The abstract equality algorithm from section 11.9.3 of the language spec is what defined == and != and it defines them such that
null == void 0
null == null
void 0 == null
where void 0 is just a reliable way of saying undefined (see below) so the answer to your question is yes, null is equal to undefined and itself and nothing else.
The relevant parts of the spec are
1. If Type(x) is the same as Type(y), then
If Type(x) is Undefined, return true.
If Type(x) is Null, return true.
...
2. If x is null and y is undefined, return true.
3. If x is undefined and y is null, return true.
...
If you're worried about undefined meaning something other than what it normally means, use void 0 instead.
null == void 0 // True
({}).x === void 0 // True
"undefined" === typeof void 0 // True
(function () {})() === void 0 // True
(undefined = 42,
undefined === void 0) // False
"undefined" === typeof undefined // False
"undefined" === typeof void 0 // True
From the language specification:
11.4.2 The void Operator
The production UnaryExpression : void UnaryExpression is evaluated as follows:
Let expr be the result of evaluating UnaryExpression/.
Call GetValue(expr).
Return undefined.
So the void prefix operator evaluates its argument and returns the special value undefined regardless of to what the global variable undefined has been changed (or whether undefined is defined :).
EDIT: In response to comments,
If you are dealing with library code that distinguishes between the two, then you need to deal with the difference. Some of the new libraries standardized by the language committee do ignore the difference : JSON.stringify([void 0]) === "[null]" but there is too much code out there that treats them subtly differently, and there are other differences :
+(null) === 0
isNaN(+undefined)
"" + null === "null"
"" + undefined === "undefined"
If you're writing any kinds of libraries that produce text or serialize/deserialize and you want to conflate the two then you can't pass undefined through and expect it to behave as null -- you need to explicitly normalize your inputs to one or the other.
Because JavaScript has both values. And while other languages may only have nil/null JavaScript grew up with undefined being the "unknown value" while null is clearly a known value to represent nothing.
Compare var x where x is undefined because no value has been assigned and var y = null where y is null. It was set to something -- a sentential representing "nothing". This core fundamental usage of undefined vs null in JavaScript runs very deep and other cases include:
A missing (or delete'd) property also yield undefined and not null (it would result in null only if null had been assigned).
Unassigned function parameters are undefined.
undefined returned from standard functions like getElementById. See comments.
Thus, in Javascript, it is often more correct to use undefined and not null. They both represent different things. A library that tries to fight this is fighting JavaScript.
Happy coding.
Personally, in almost all cases I avoid an explicit check for undefined or null. I believe that in most -- but not all -- cases all false values should be equivalent and that it is the callers responsibility to conform to the public contract stated.
Because of this belief I would consider the comparison x == null on the verge of trying to guard too much and yet too little, but in the case of catching null or undefined, it works, as pointed out. Go start a trend ;-)
Because of this:
var myVar1;
var myVar2 = null;
if (myVar1 === null) alert('myVar1 is null');
if (myVar1 === undefined) alert('myVar1 is undefined');
if (myVar2 === null) alert('myVar2 is null');
if (myVar2 === undefined) alert('myVar2 is undefined');
Anything set to null is not undefined - it's defined as null.
Reading Javascript: The Good parts, it seems that only null and undefined are equivalent
JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=. The good ones
work the way you would expect. If the two operands are of the same type and have the same value, then ===
produces true and !== produces false. The evil twins do the right thing when the operands are of the
same type, but if they are of different types, they attempt to coerce the values. The rules by which they do that
are complicated and unmemorable. These are some of the interesting cases:
'' == '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
"JavaScript: The Good Parts by Douglas Crockford. Copyright 2008 Yahoo! Inc.,
978-0-596-51774-8."

When is null or undefined used in JavaScript? [duplicate]

This question already has answers here:
What is the difference between null and undefined in JavaScript?
(38 answers)
Closed 8 years ago.
I am really confused as to when JavaScript returns null or undefined. Also different browsers seem to be returning these differently.
Could you please give some examples of null/undefined with the browsers that return them.
While I am now clear on the undefined aspect, I am still not 100% clear on null. Is it similar to a blank value?
E.g. You have a text box which does not have any value set. Now when you try to access its value, will it be null or undefined and are they similar?
I find that some of these answers are vague and complicated, I find the best way to figure out these things for sure is to just open up the console and test it yourself.
var x;
x == null // true
x == undefined // true
x === null // false
x === undefined // true
var y = null;
y == null // true
y == undefined // true
y === null // true
y === undefined // false
typeof x // 'undefined'
typeof y // 'object'
var z = {abc: null};
z.abc == null // true
z.abc == undefined // true
z.abc === null // true
z.abc === undefined // false
z.xyz == null // true
z.xyz == undefined // true
z.xyz === null // false
z.xyz === undefined // true
null = 1; // throws error: invalid left hand assignment
undefined = 1; // works fine: this can cause some problems
So this is definitely one of the more subtle nuances of JavaScript. As you can see, you can override the value of undefined, making it somewhat unreliable compared to null. Using the == operator, you can reliably use null and undefined interchangeably as far as I can tell. However, because of the advantage that null cannot be redefined, I might would use it when using ==.
For example, variable != null will ALWAYS return false if variable is equal to either null or undefined, whereas variable != undefined will return false if variable is equal to either null or undefined UNLESS undefined is reassigned beforehand.
You can reliably use the === operator to differentiate between undefined and null, if you need to make sure that a value is actually undefined (rather than null).
According to the ECMAScript 5 spec:
Both Null and Undefined are two of the six built in types.
4.3.9 undefined value
primitive value used when a variable has not been assigned a value
4.3.11 null value
primitive value that represents the intentional absence of any object value
The DOM methods getElementById(), nextSibling(), childNodes[n], parentNode() and so on return null (defined but having no value) when the call does not return a node object.
The property is defined, but the object it refers to does not exist.
This is one of the few times you may not want to test for equality-
if(x!==undefined) will be true for a null value
but if(x!= undefined) will be true (only) for values that are not either undefined or null.
You get undefined for the various scenarios:
You declare a variable with var but never set it.
var foo;
alert(foo); //undefined.
You attempt to access a property on an object you've never set.
var foo = {};
alert(foo.bar); //undefined
You attempt to access an argument that was never provided.
function myFunction (foo) {
alert(foo); //undefined.
}
As cwolves pointed out in a comment on another answer, functions that don't return a value.
function myFunction () {
}
alert(myFunction());//undefined
A null usually has to be intentionally set on a variable or property (see comments for a case in which it can appear without having been set). In addition a null is of type object and undefined is of type undefined.
I should also note that null is valid in JSON but undefined is not:
JSON.parse(undefined); //syntax error
JSON.parse(null); //null
I might be missing something, but afaik, you get undefined only
Update: Ok, I missed a lot, trying to complete:
You get undefined...
... when you try to access properties of an object that don't exist:
var a = {}
a.foo // undefined
... when you have declared a variable but not initialized it:
var a;
// a is undefined
... when you access a parameter for which no value was passed:
function foo (a, b) {
// something
}
foo(42); // b inside foo is undefined
... when a function does not return a value:
function foo() {};
var a = foo(); // a is undefined
It might be that some built-in functions return null on some error, but if so, then it is documented. null is a concrete value in JavaScript, undefined is not.
Normally you don't need to distinguish between those. Depending on the possible values of a variable, it is sufficient to use if(variable) to test whether a value is set or not (both, null and undefined evaluate to false).
Also different browsers seem to be returning these differently.
Please give a concrete example.
Regarding this topic the specification (ecma-262) is quite clear
I found it really useful and straightforward, so that I share it:
- Here you will find Equality algorithm
- Here you will find Strict equality algorithm
I bumped into it reading "Abstract equality, strict equality, and same value" from mozilla developer site, section sameness.
I hope you find it useful.
A property, when it has no definition, is undefined.
null is an object. It's type is null. undefined is not an object, its type is undefined.
This is a good article explaining the difference and also giving some examples.
null vs undefined

undefined and null

undefined === null => false
undefined == null => true
I have thought about the reason of undefined == null and found out only one case:
if(document.getElementById() == null) ....
Is there any other reason to make (undefined === null) == false ?
Is there any other examples of use === - operation in javascript?
Is there any other reason to make (undefined === null) == false ?
They are not equal so the Strict Equality Comparison Algorithm considers them to be false.
Is there any other examples of use === - operation in javascript?
The === gives the most predictable result. I only use == when I have a specific purpose for type coercion. (See Abstract Equality Comparison Algorithm.)
null and undefined are two different concepts. undefined is the lack of value (if you define a variable with var without initializing it, it doesn't contain null, but undefined), while with null the variable exists and is initialized with the value null, which is a special type of value.
JavaScript equality operator is broken though, Crockford found out that it lacks transitivity and for this reason suggests to use always the strict equality (===). Consider this table published in Javascript 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
=== is strict equal.
Undefined and null are not the same thing.
== uses type coercion.
null and undefined coerce to each other.
Type coercion (using the == operator) can lead to undesired or unexpected results. After following all the talks I could find of Douglas Crockford on the net (mostly Yahoo video) I got used to using === all te time. Given my default usage of the strict equal operator I would be more interested in type coercion javascript use cases ;~) nowadays.

Categories