Skip to content

Improve concept exercise: Null and Undefined #1170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions concepts/null-undefined/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"blurb": "In JavaScript there are two different entities that represent the absence of a (meaningful) value: `null` and `undefined`.",
"authors": ["SleeplessByte", "Jlamon", "junedev"],
"contributors": []
}
161 changes: 161 additions & 0 deletions concepts/null-undefined/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# About

In contrast to many other languages, there are two different entities in JavaScript that represent the absence of a (meaningful) value.
There is `null` and `undefined`.

## Null

The primitive value `null` is used as intentional "empty value" for a variable.
In other languages a similar construct might be used only for (missing) objects or pointer types.
In JavaScript `null` generally represents an empty value for any type.

```javascript
let name = null;
// name is intentionally set to "empty" because it is not
// available
```

You can check whether a variable is null by using the [strict equality operator][mdn-strict-equality] `===`.
Although `null` is a primitive value, the [`typeof` operator][mdn-typeof] "wrongly" returns `object` for [historic reasons][mdn-typeof-null].
That means it cannot be used by itself to check whether a variable is null.

```javascript
let name = null;

name === null;
// => true

// Pitfall:
typeof name;
// => 'object'
```

## Undefined

> A variable that has not been assigned a value is of type `undefined`.<sup>1</sup>

That means while `null` represents an empty value (but still a value), `undefined` represents the total absence of a value. 🤯

`undefined` appears in different contexts.

- If a variable is declared without a value (initialization), it is `undefined`.
- If you try to access a value for a non-existing key in an object, you get `undefined`.
- If a function does not return a value, the result is `undefined`.
- If an argument is not passed to a function, it is `undefined`, unless that argument has a default value.

```javascript
let name;
console.log(name);
// => undefined

let obj = { greeting: 'hello world' };
console.log(obj.missingKey);
// => undefined

function returnNothing() {
return;
}
console.log(returnNothing());
// => undefined
```

You can check whether a variable is undefined using the strict equality operator `===` or the `typeof` operator.

```javascript
let name;

name === undefined;
// => true

typeof name === 'undefined';
// => true
```

It is not recommended to manually assign `undefined` to a variable, always use `null` instead to make it clear you set an empty value intentionally.

## Optional Chaining

As mentioned above, accessing a non-existent key in an object returns `undefined` in JavaScript.
However if you try to retrieve a nested value and the parent key does not exist, the evaluation of the nested key is performed on `undefined` and leads to `TypeError: Cannot read property ... of undefined`.
Theoretically, you would always need to check the parent key exists before you can try to retrieve the nested key.
This was often done with the AND operator `&&` but for deeply nested values this leads to very lengthy expressions.

```javascript
obj.level1 && obj.level1.level2 && obj.level1.level2.level3;
```

To solve this problem, [optional chaining][mdn-optional-chaining] was added to the language specification in 2020.
With the optional chaining operator `?.` you can ensure that JavaScript only tries to access the nested key if the parent was not `null` or `undefined`.
Otherwise `undefined` is returned.

```javascript
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};

obj.residence;
// => undefined

obj.address.zipCode;
// => undefined

obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined

obj.residence?.street;
// => undefined

obj.residence?.street?.number;
// => undefined
```

## Nullish Coalescing

There are situations where you want to apply a default value in case a variable is null or undefined.
In the past this was often times done with a ternary operator `?` or by utilizing lazy evaluation of the OR operator `||`.
This has the disadvantage that the default value is applied in all cases where the variable is [falsy][mdn-falsy] (e.g. `''` or `0`), not only when it is null or undefined.
This can easily cause unexpected outcomes.

```javascript
let amount = null;
amount = amount || 1;
// => 1

amount = 0;
amount = amount || 1;
// => 1

amount = 0;
amount ? amount : 1;
// => 1
```

To address this, the [nullish coalescing operator][mdn-nullish-coalescing] `??` was introduced.
Just like optional chaining, it was added to the language specification in 2020.
The nullish coalescing operator `??` returns the right-hand side operand only when the left-hand side operand is `null` or `undefined`.
Otherwise the left-hand side operand is returned.
With that, a default value can now be applied more specifically.

```javascript
let amount = null;
amount = amount ?? 1;
// => 1

amount = 0;
amount = amount ?? 1;
// => 0
```

---

[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (accessed June 4, 2021).

[mdn-strict-equality]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality
[mdn-typeof]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
[mdn-typeof-null]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof#typeof_null
[mdn-optional-chaining]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
[mdn-falsy]: https://developer.mozilla.org/en-US/docs/Glossary/Falsy
[mdn-nullish-coalescing]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
99 changes: 99 additions & 0 deletions concepts/null-undefined/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Introduction

In contrast to many other languages, there are two different entities in JavaScript that represent the absence of a (meaningful) value.
There is `null` and `undefined`.

## Null

The primitive value `null` is used as intentional "empty value" for variables of any type.

```javascript
let name = null;
// name is intentionally set to "empty" because it is not
// available
```

You can check whether a variable is null by using the [strict equality operator][mdn-strict-equality] `===`.

```javascript
let name = null;

name === null;
// => true
```

## Undefined

> A variable that has not been assigned a value is of type `undefined`.<sup>1</sup>

That means while `null` represents an empty value (but still a value), `undefined` represents the total absence of a value. 🤯

`undefined` appears in different contexts.

- If a variable is declared without a value (initialization), it is `undefined`.
- If you try to access a value for a non-existing key in an object, you get `undefined`.
- If a function does not return a value, the result is `undefined`.
- If an argument is not passed to a function, it is `undefined`, unless that argument has a default value.

```javascript
let name;
console.log(name);
// => undefined
```

You can check whether a variable is undefined using the strict equality operator `===`.

```javascript
let name;

name === undefined;
// => true
```

## Optional Chaining

If you try to retrieve a nested value in an object but the parent key does not exist, JavaScript will throw an error.
To easily avoid this, optional chaining was added to the language specification in 2020.
With the optional chaining operator `?.` you can ensure that JavaScript only tries to access the nested key if the parent was not `null` or `undefined`.
Otherwise `undefined` is returned.

```javascript
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};

obj.address.zipCode;
// => undefined

obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined

obj.residence?.street;
// => undefined
```

## Nullish Coalescing

There are situations where you want to apply a default value in case a variable is null or undefined (but only then).
To address this, the nullish coalescing operator `??` was introduced in 2020.
It returns the right-hand side operand only when the left-hand side operand is `null` or `undefined`.
Otherwise the left-hand side operand is returned.

```javascript
let amount = null;
amount = amount ?? 1;
// => 1

amount = 0;
amount = amount ?? 1;
// => 0
```

---

[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (accessed June 4, 2021).

[mdn-strict-equality]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
[
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null",
"description": "Nullability - MDN Docs"
"description": "MDN: null"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator",
"description": "Nullish coalescing operator - MDN Docs"
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined",
"description": "MDN: undefined"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining",
"description": "Optional chaining - MDN Docs"
"description": "MDN: Optional chaining"
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator",
"description": "MDN: Nullish coalescing operator"
}
]
5 changes: 0 additions & 5 deletions concepts/nullability/.meta/config.json

This file was deleted.

60 changes: 0 additions & 60 deletions concepts/nullability/about.md

This file was deleted.

13 changes: 0 additions & 13 deletions concepts/nullability/introduction.md

This file was deleted.

Loading