10

So, I am reading optional chaining in JavaScript and a question popped into my head.

Consider the code below:

let person = null
let street = person?.street // returns undefined

My question is that, if the variable person is null to begin with, then why is doing optional chaining result to setting the variable as undefined and not null?

If the person was undefined, then I guess, for me, setting it to undefined is reasonable because the variable is of course undefined, like the below:

let person
let street = person?.street // returns undefined 

PS: I'm sorry if this is a stupid question, I'll delete it if someone agrees. :)

PPS: If this question is duplicated, pls drop the link and I'll give it a go. Thank you, very much.

2
  • 1
    Does the first paragraph answer your question? Commented Apr 10, 2022 at 15:40
  • @Palladium02 I kinda get that it is similar to street = (person == null || person == undefined) ? undefined : person.name. I'm kind of confused as to why undefined is explicitly returned and not the person (to get null or undefined depending on the nature of the person variable) Commented Apr 10, 2022 at 15:47

4 Answers 4

11

An optional chain does not evaluate to the nullish value on which the property was accessed, but to undefined - just like you get undefined when a property does not exist in an object.

Conceptually, think of person?.street not as

person && person.street

but rather as

(person ?? {}).street

Though accurately (especially when chained further, since it does short-circuit instead of evaluating the rest of the chain) it's really

person != null ? person.street : undefined

See also the FAQ on the optional chaining proposal:

Why does (null)?.b evaluate to undefined rather than null?

Neither a.b nor a?.b is intended to preserve arbitrary information on the base object a, but only to give information about the property "b" of that object. If a property "b" is absent from a, this is reflected by a.b === undefined and a?.b === undefined.

In particular, the value null is considered to have no properties; therefore, (null)?.b is undefined.

Sign up to request clarification or add additional context in comments.

1 Comment

If a property "b" is absent from a, this is reflected by a.b === undefined and a?.b === undefined. I see. That makes sense. Thank you.
4

You can always fallback to null using the logical OR operator ||

const person = null
let street = person?.street || null
console.log(street)

1 Comment

Beware this will convert all falsy values to null (not just undefined, but also false, 0, the empty string and others will also be converted to null)
0

Please read the manual about optional chaining.

The ?. operator is like the . chaining operator, except that instead of causing an error if a reference is nullish (null or undefined), the expression short-circuits with a return value of undefined. When used with function calls, it returns undefined if the given function does not exist.

5 Comments

I kinda get that it is similar to street = (person == null || person == undefined) ? undefined : person.name. I'm kind of confused as to why undefined is explicitly returned and not the person (to get null or undefined depending on the nature of the person variable).
To keep the return value consistent when the variable has nullish values. If we needed to return either null or undefined or the value of person - then, we may as well use person directly, no?
@jsN00b, oh yeah, point taken. My little brain said "If the variable was null to begin with, then why make it undefined during an optional chaining?".
@Hansel you can imagine it (to a certain extent) like it's just softening the rules in such a way that null.anything and undefined.anything are undefined (instead of crashing) much like ({}).anything is undefined as well (plus null() and undefined() would then also return undefined).
@Seven Just adding that person == null || person == undefined is equal to person == null, since you used == and not ===. I do get the message you were trying to convey (if person is exactly null or undefined), and that message was perhaps more clear when explicitly stating both conditions, but then I think you should have used === as well to avoid further confusion.
0

The reason the result is undefined and not null is because of optional chaining (?.).


If optional chaining wasn't available, your code would've resulted in an error, saying that null has no properties.

const person = null;
person.street // ERROR!

But, since you have optional chaining, it only results in undefined.

const person = null;
person?.street // undefined

This is why optional chaining results in undefined (if the value is null or undefined); to avoid throwing an error!

Hope this answered your question!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.