To ensure readability, this paper uses free translation instead of literal translation.
Some of the features of JS have dramatically changed the way we code.Solutions, arrow functions, classes, and module systems that have the greatest impact on our code since ES6.
By August 2019, a new alternative chain proposal has entered the third stage, which is a good improvement.Optional links change the way attributes are accessed from deep object structures.
Let's see what this is.
This week, Daqian World has a draw with prizes: column "Hearing the Wind in the Left Ear" x3, technical book x5. Welcome to Reply: Draw Prizes
problem
Because of the dynamic nature of JS, objects can have many different layers of nested object structure.
Usually, when we deal with the following objects:
- Get remote JSON data
- Use Configuration Objects
- Has optional properties
Although JS supports different hierarchies of data structures for objects, the complexity increases when accessing the properties of such objects.
bigObject can have different sets of properties at runtime
// Nested Version const bigObject = { // ... prop1: { //... prop2: { // ... value: 'Some value' } } }; // Simple version const bigObject = { // ... prop1: { // Nothing here } };
Therefore, you must manually check for the existence of attributes
if (bigObject && bigObject.prop1 != null && bigObject.prop1.prop2 != null) { let result = bigObject.prop1.prop2.value; }
This is too long to write, so it's best to avoid it.
Let's see how the optional chain solves this problem to reduce redundant code.
2. Easy in-depth access to properties
Design an object to hold movie information.The object contains the required title property, as well as optional director s and actors.
The movieSmall object only contains title, while movieFull contains the complete set of properties:
const movieSmall = { title: 'Heat' }; const movieFull = { title: 'Blade Runner', director: { name: 'Ridley Scott' }, actors: [{ name: 'Harrison Ford' }, { name: 'Rutger Hauer' }] };
Write a function to get the directory.Keep in mind that directors may not exist.
function getDirector(movie) { if (movie.director != null) { return movie.director.name; } } getDirector(movieSmall); // => undefined getDirector(movieFull); // => 'Ridley Scott'
The if(movie.director){...} condition is used to verify that the directory property is defined.Without this precaution, when accessing the directory of the movieSmall object, the JS throws TypeError: Cannot read property'name'of undefined.
This scenario is best suited to use the functionality of the optional chain, as shown below, where the code is much simpler.
function getDirector(movie) { return movie.director?.name; } getDirector(movieSmall); // => undefined getDirector(movieFull); // => 'Ridley Scott'
Can be found in the movie.director?.name expression?: Optional link operator.
In movieSmall, there is no directory attribute.So, movie.director?The result of.Name is undefined.Optional chain operators prevent throwing TypeError: Cannot read property'name'of undefined.
Simply put, snippets:
let name = movie.director?.name;
Equivalent to
let name; if (movie.director != null) { name = movie.director.name; }
?. Simplify the getDirector() function by reducing two lines of code, which is why I like the optional chain.
2.1 Array Items
Optional chain functionality can do more.You can freely use multiple optional link operators in the same expression, and you can even use them to safely access array items.
The next task is to write a function that returns the name from the actors in the movie.
In a movie object, the actors array can be empty or even missing, so additional criteria must be added to make it empty.
function getLeadingActor(movie) { if (movie.actors && movie.actors.length > 0) { return movie.actors[0].name; } } getLeadingActor(movieSmall); // => undefined getLeadingActor(movieFull); // => 'Harrison Ford'
The if (movie.actors && movies.actors.length > 0) {...} condition mainly determines that movies contain actors and that there is at least one actor for this property.
With optional links, the code is also concise, as follows:
function getLeadingActor(movie) { return movie.actors?.[0]?.name; } getLeadingActor(movieSmall); // => undefined getLeadingActor(movieFull); // => 'Harrison Ford'
Actors?.Make sure the actors attribute exists, [0]?.Make sure the first actor exists in the list.
3.nullish coalescing
A name is nullish coalescing operator New proposal?Handle undefined or null and default them to specific values.
Expression variable?? If the variable undefined or null, the default value is the specified value.
const noValue = undefined; const value = 'Hello'; noValue ?? 'Nothing'; // => 'Nothing' value ?? 'Nothing'; // => 'Hello'
Next, use?? to optimize the getLeading() function to return "Unknown actor" when there is no actor in the movie object
function getLeadingActor(movie) { return movie.actors?.[0]?.name ?? 'Unknown actor'; } getLeadingActor(movieSmall); // => 'Unknown actor' getLeadingActor(movieFull); // => 'Harrison Ford'
4. Three forms of optional chains
We can use the following three types of optional chains.
First, object?.property is used to access static properties:
const object = null; object?.property; // => undefined
Second, object?.[expression] is used to access dynamic properties or array items:
// firstly const object = null; const name = 'property'; object?.[name]; // => undefined // second const array = null; array?.[0]; // => undefined
Third: object?.([arg1, [arg2,...]) Executes an object method
const object = null; object?.method('Some value'); // => undefined
Combine the three to create an optional chain:
const value = object.maybeUndefinedProp?.maybeNull()?.[propName];
5. Short circuit: encountered null/undefined stop
The interesting thing about the optional link operator is that as long as it's on the left leftHandSide?When.rightHandSide encounters an invalid value, right-hand access stops, which is called short-circuit.
Take an example:
const nothing = null; let index = 0; nothing?.[index++]; // => undefined index; // => 0
6. When to use optional chains
Do not rush to use the optional chain operator to access any type of property: this can lead to incorrect use.
6.1 Accessing potentially invalid properties
?.Typically used for attributes that may be empty: maybeNullish?.prop.Use the property accessor:.Property or [propExpression] when you are certain that the property is not empty.
// good function logMovie(movie) { console.log(movie.director?.name); console.log(movie.title); } // not good function logMovie(movie) { // director needs optional chaining console.log(movie.director.name); // movie doesn't need optional chaining console.log(movie?.title); }
6.2 There are usually better choices
The following function hasPadding() receives a style object for an optional padding attribute.Padding has left, top, right, bottom optional attributes.
Try using the optional chain operator:
function hasPadding({ padding }) { const top = padding?.top ?? 0; const right = padding?.right ?? 0; const bottom = padding?.bottom ?? 0; const left = padding?.left ?? 0; return left + top + right + bottom !== 0; } hasPadding({ color: 'black' }); // => false hasPadding({ padding: { left: 0 } }); // => false hasPadding({ padding: { right: 10 }}); // => true
Although the function correctly determines whether an element has a padding, using an optional chain for each attribute is a little too cumbersome.
A better way is to default the padding object to zero using the object extension operator
function hasPadding({ padding }) { const p = { top: 0, right: 0, bottom: 0, left: 0, ...padding }; return p.top + p.left + p.right + p.bottom !== 0; } hasPadding({ color: 'black' }); // => false hasPadding({ padding: { left: 0 } }); // => false hasPadding({ padding: { right: 10 }}); // => true
This is simpler than the optional chain.
BUGs that may exist after code deployment are not known in real time. In order to solve these BUGs afterwards, a lot of time has been spent debugging the log. By the way, a useful BUG monitoring tool is recommended. Fundebug.
Communication
The dry goods series articles are summarized below, feel good to order Star, welcome to join the group to learn from each other.
https://github.com/qq44924588...
I am Xiao Zhi, the author of the public number "Move the World", a fan of keeping learning about front-end technology.I often share what I've learned and what I've seen. On the way to the next level, I'll reluctantly!
Focus on the public number and reply to the benefits in the background. You can see the benefits, you know.