undefined means a variable has been declared but has not yet been assigned a value :
var testVar;
console.log(testVar); //shows undefined
console.log(typeof testVar); //shows undefined
null is an assignment value. It can be assigned to a variable as a representation of no value :
var testVar = null;
console.log(testVar); //shows null
console.log(typeof testVar); //shows object
From the preceding examples, it is clear that undefined and null are two distinct types: undefined is a type itself (undefined) while null is an object.
Proof :
console.log(null === undefined) // false (not the same type)
console.log(null == undefined) // true (but the "same value")
console.log(null === null) // true (both type and value are the same)
and
null = 'value' // Uncaught SyntaxError: invalid assignment left-hand side
undefined = 'value' // 'value'
Answer from sebastian on Stack OverflowI know java the most but recently started learning JavaScript, which treats null and undefined as two separate things. From what I remember me and peers used the two terms interchangeably in Java. Is there anything such as undefined in Java, or is it just null value? I might have to be careful about using the term undefined for Java then later.
Videos
undefined means a variable has been declared but has not yet been assigned a value :
var testVar;
console.log(testVar); //shows undefined
console.log(typeof testVar); //shows undefined
null is an assignment value. It can be assigned to a variable as a representation of no value :
var testVar = null;
console.log(testVar); //shows null
console.log(typeof testVar); //shows object
From the preceding examples, it is clear that undefined and null are two distinct types: undefined is a type itself (undefined) while null is an object.
Proof :
console.log(null === undefined) // false (not the same type)
console.log(null == undefined) // true (but the "same value")
console.log(null === null) // true (both type and value are the same)
and
null = 'value' // Uncaught SyntaxError: invalid assignment left-hand side
undefined = 'value' // 'value'
The difference can be explained with toilet tissue holder:
A non-zero value is like a holder with roll of toilet tissue and there's tissue still on the tube.
A zero value is like a holder with an empty toilet tissue tube.
A null value is like a holder that doesn't even have a tissue tube.
An undefined value is similar to the holder itself being missing.

both are falsy values that denote absence of data, the only difference is apparently whether or not it was "intentional"
The main problem with Javascript having both null and undefined is that they are used inconsistently, even in standardised APIs. There is no absolute authority which says what each should be used to mean or indicate, and so different programmers imbue them with different meanings. Library code mostly has to treat them the same way, because there is no agreed standard for how they should be treated differently.
Perhaps to you, null means an "intentionally" missing value and undefined means an "unintentionally" missing value, but this isn't universal. The ECMAScript specification doesn't seem to have anything to say on the subject. MDN advises that null means "the intentional absence of any object value" but doesn't give the opposite advice for undefined. And as an example, canvas.getContext('2d') returns null when the same canvas is already in use in a 3D context, something very unlikely to be done intentionally.
Worse, "intentionally missing" isn't as clear a distinction as you might think. For example, function parameters take the value undefined when no argument is provided, but an argument could be missing either intentionally or unintentionally. Likewise, map.get(missingKey) returns undefined, but the key could be absent either intentionally or unintentionally. (Meanwhile, localStorage.getItem returns null instead in the same case.) The intent where a value is produced may also be different than where it is used.
As a result, if you come across some variable which might hold either an object or null or undefined, you will have to read the comments (hopefully there are some!) to figure out what the author intended by that. Perhaps the author didn't even intend to treat them differently, just there is a mix of undefined and null because those values came from different places and there was no need to unify them.
If instead there was a language-wide authoritative standard which said undefined means one thing and null means another, then this would be less of a problem, although there would still be code which doesn't follow the standard. That said, if you can think of a clear difference between what these two values should mean in your language, then you can probably think of better names for these values which would communicate those meanings.
It is useful but not necessary and there are better alternatives.
Dynamically typed languages have the limitations that they can only discover concrete types of values. That means they cannot differentiate between levels of a value being undefined: a function taking a value: Option[T] = None cannot find out whether it received the default None or was passed one if T is itself some Option[T'].
This can be practically fixed by having more than one "not defined" value: A function taking a value: T = undef can trivially separate the case of default undef and passed in None.
Of course this only shifts the problem: While for many practical problems eliminating half the collisions is enough, collisions still occur. A function that has to operate on both default and passed in undef/None still cannot separate the cases.
A more thorough approach is to allow/encourage defining new "not defined" values/types for each use. For example, Python has the idiom of using a hidden, bare object() as needed.
# placeholder with unique identity
_no_default = object()
def find(predicate, values, default = _no_default):
...
Of course a language can provide tools and syntactic sugar to make this simpler.
Since switching to TypeScript I have been using a lot of optional properties, for example:
type store = {
currentUserId?: string
}
function logout () {
store.currentUserId = undefined
}However my coworkers and I have been discussing whether null is a more appropriate type instead of undefined, like this:
type store = {
currentUserId: string | null
}
function logout () {
store.currentUserId = null
}It seems like the use of undefined in TypeScript differs slightly from in Javascript.
Do you guys/girls use undefined or null more often? And, which of the examples above do you think is better?