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?
Please consider the following:
var myFruits = ['Banana', 'Apple', 'Strawberry'];// SOME CODING// SOME CODINGmyFruits = undefined; // Is this better?myFruits = null; // or is this better?
Further question, what is the distinction between the two? Is there any cases where only null is used or undefined is used? Thanks.
Videos
Most programming languages have a single value to indicate the absence of something, which is often called null and is used to represent a variable that has no value associated with it.
But JavaScript is different. Someone who is just starting out with JavaScript or coming from a different language usually finds it hard to understand, why there are two values that indicate absence: null and undefined
Check out the post to learn how these two are different.
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.

-
Undefined: The variable exists, but it has not yet been give a value, and thus it has a default value of undefined.
-
Null: The variable exists only as a reference. It does not yield any value.
Follow-up: Why is it useful to distinguish between null and undefined in javascript?
This does not completely cover all cases.
Undefined doesn't necessarily mean that a variable exists but hasn't been given a value yet. It's also possible to explicitly give a variable the value of "undefined", and it is sometimes returned when trying to look up an object member that doesn't exist. E.g. when looking up myObj.thisDoesntExist.
Variables that are set to null do return a value: the value being null.
They need to both be taken into account because they behave slightly differently. For example, if you have a function with default arguments, the default argument will be used if you pass undefined (or no argument at all) - but if you pass null, then your null will be used.
Not... exactly.
undefined means that either the value of the variable has not yet been defined, OR you've explicitly given the variable the value of undefined.
null is essentially an empty value that's separate from more generic (specific?) empty values, like empty string or zero or empty array. It's the equivalent of saying "this box (variable) that can hold a value currently is empty".
Finally, not defined (not really a value, but worth mentioning) is a special error-case when you try to access a variable before initializing it. For example, if you load an empty page and type in the console console.log(derp), you'll get a message that says "Uncaught ReferenceError: derp is not defined". This final value is a little strange, since it's almost the same as undefined, but won't allow you to access the variable in any format; It doesn't exist yet.
I never understood why JS makes a distinction between the two. Other programming languages don't have undefined and only have a null value.
I understand that they represent different things, but in practice they are used in exactly the same way. Accessing a property on an undefined/null value gives the same error Cannot read property x of undefined/null. I have never found it useful to make a distinction between the two and I usually have to always make double checks like if (x === undefined || x === null).
Was this just a poor design decision that is here to stay? If someone actually has a use case for knowing the distinction between null vs undefined, I would like to hear it.
Suppose I am collecting a sample of movie ratings from 1000 random people to see if they are good. The movies are rated as Number types from -10 to 10.
For example
-
undefined = no such movie (no value exists)
-
null = haven't watched the movie (exists, but left undeclared)
-
0 = no opinion about the movie (normal value)
-
NaN = I can't tell if I like it or hate it (indeterminate or invalid number)
Is it correct and is the system good? Tell me in the comments below!
Hey! What are your thoughts on explicit returning undefined in a function vs returning null, this in the absence of what you asked the function for.
Let's take these functions as an exampletype getUser = (id: string): User | undefined vs type getUser = (id: string): User | NULL
What are your thoughts on this? Good and bad etc
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.
So I'm usually more of a server side developer, but lately I've been working with more of the client code at work. I understand what undefined and null are in JavaScript, but I find myself always checking for both of them. In fact, when checking if a String property exists, I end up writing this:
if(value !== undefined && value !== null && value !== '')
I figure there is a better way than this, and it's probably because I'm not 100% clear of when to check for what. So if someone could help fill me in here on the rules of when to check for undefined vs null, that would be great.
TL;DR: Use value != null. It checks for both null and undefined in one step.
In my mind, there are different levels of checking whether something exists:
0) 'property' in object - Returns true if the property exists at all, even if it's undefined or null.
-
object.property !== undefined- Returns true if the property exists and is not undefined. Null values still pass. -
object.property != null- Return true if the property exists and is not undefined or null. Empty strings and 0's still pass. -
!!object.property- Returns true if the property exists and is "truthy", so even 0 and empty strings are considered false.
From my experience, level 2 is usually the sweet spot. Oftentimes, things like empty strings or 0 will be valid values, so level 3 is too strict. On the other hand, levels 0 and 1 are usually too loose (you don't want nulls or undefineds in your program). Notice that level 1 uses strict equality (!==), while level 2 uses loose equality (!=).
I would just say
if (value) {
// do stuff
}
because
'' || false
// false
null || false
// false
undefined || false
//false
Edit:
Based on this statement
I end up writing this: if(value !== undefined && value !== null && value !== '')
I initially assumed that what OP was really looking for was a better way to ask "is there a value?", but...
if someone could help fill me in here on the rules of when to check for undefined vs null, that would be great.
If you're looking to see if something is "truthy":
if (foo.bar) {
alert(foo.bar)
}
This won't alert if value is '', 0, false, null, or undefined
If you want to make sure something is a String so you can use string methods:
if (typeof foo.bar === 'string') {
alert(foo.bar.charAt(0))
}
This won't alert unless value is of type 'string'.
So.. "when to check for undefined vs null"? I would just say, whenever you know that you specifically need to check for them. If you know that you want to do something different when a value is null vs when a value is undefined, then you can check for the difference. But if you're just looking for "truthy" then you don't need to.