As one of the most popular languages, JavaScript’s syntax is flexible and continuously absorbs new features each year. Even seasoned professionals occasionally come across some underestimated JavaScript features and tricks. This article will share these tricks for discussion and exploration.
Using flatMap
Although some JavaScript methods are barely known, they possess the potential to enhance coding efficiency by resolving unique challenges, such as flatMap().
The array method flatMap() is essentially a combination of map() and flat(). The difference is that flatMap can only flatten 1 level, while flat can specify the number of levels to flatten. FlatMap is slightly more efficient than calling these two methods separately.
Using flat + map:
|
|
Using flatMap:
|
|
Although flatMap is a method, it still generates an intermediate array (which refers to a temporary array created for garbage collection). FlatMap is highly suitable for use in scenarios requiring flexibility and readability.
Array Method Order
javascript has dozens of array methods that can be used in combination. They look something like this:
|
|
The above code looks good, but there is an issue — sorting is done for the array before filtering. If the filtering is done before the sorting, we can accomplish fewer tasks, thereby optimizing the code.
|
|
Make full use of reduce
When writing JavaScript, sometimes we need to provide data in a key-value grouping format. Most developers will use the .forEach() method or map() method, similar to this:
|
|
Here, it’s better to use forEach rather than the map method, because the map method returns a new array, and the performance overhead of array creation and value assignment is relatively large, especially when the data volume is large, this will not happen in forEach.
Another quite clean and readable method is using the reduce method from the array:
|
|
Note how we’re using an empty object {} as the initial value for the reduce operation. This object becomes the new accumulator.
Make full use of generator
Generators and iterators might be the least frequently used code by JavaScript developers, as their knowledge is confined to coding interviews. (Because there’s a better syntax sugar async/await? 😂)
The generator is a powerful method to control asynchronous programming, generate iterable objects and multiple values. Generators are different from traditional functions. They can start and stop execution many times. That allows them to generate a lot of values and to continue their execution later, which makes them extremely suitable for managing asynchronous operations, constructing iterators, and dealing with endless data streams.
Imagine a scenario where the amount of data from the database/API might be infinite, and you need to transfer them to the front-end, how would you do it?
In this case, the most common solution in react is infinite loading. If it is in node or native JS, how would you implement a function like infinite loading.
|
|
This is where iterators are really useful, instead of streaming a large amount of request data to local storage or some location. This is one of the ways to perform this operation using asynchronous generators, so we can solve the problem of infinite loading in JS.
Making Good Use of Console
Console is not just about console.log(). In actual production, a well-packaged log library will typically be used. The console object actually has many useful built-in methods, which can help you improve the quality and readability of your debugging output. Mastering them can help you debug and solve problems in your code more easily.
|
|
Deep Copy with structuredClone()
Previously, if a developer wanted to do a deep copy of an object, they usually had to rely on a third-party library or manually implement a deep copy, or adopt a hack like const cloneObj = JSON.parse(JSON.stringify(obj));. But it had a lot of shortcomings when dealing with more complex objects containing circular references or data types that don’t conform to JSON (such as Map and Set, Blob, etc.)
Now, JavaScript has a built-in method called structuredClone(). This method provides a simple and effective way to deep clone objects and is suitable for most modern browsers and Node.js v17 and above.
|
|
Unlike the well-known JSON.parse(JSON.stringify()), structuredClone() allows you to clone circular references, which makes it the simplest method to use deep copy in JavaScript currently.
Tagged Templates
Tagged Templates is a more advanced form of template strings (backticks) that allows you to parse template literals using functions.
I only learned about this advanced feature when Next.js 14 was released and people were talking about a certain picture🫡. Although this feature was included in ES6 and has been around for 8 years!!! But I bet there are only a handful of people who know and have used this feature.
If you don’t understand how Tagged Templates work, let me briefly explain it with an example:
|
|
As you can see, the way Tagged Templates work is to pass all the strings in the template string to the first argument of the function as an array. The remaining arguments are then inserted directly into the strings according to the respective expressions. Tagged Templates pass literal strings and the results of expressions to the function, and then the function can operate and return them in a custom way. This allows developers to appropriately escape and verify inputs when building SQL queries, thus preventing SQL injection attacks.
Tagged template strings can be used for many purposes, such as security, i18n, and localization, etc.
Nullish Coalescing Operator??
The Nullish Coalescing Operator ??
is a logical operator that returns its right-hand operand when its left-hand operand is null or undefined, otherwise, it returns its left-hand operand.
|
|
What’s worth mentioning about this? Is not ||
enough? Because one question that may confuse many people when learning JS is the difference between false and falsy, and the main difference between ??
and ||
lies in
??
operator only returns its right-hand operand if the left-hand operand is null or undefined.
||
operator treats all falsy values of its left operand’s result as its right operand.
Here are some examples:
|
|
For JS’s falsy value judgement, you can refer to this table: JavaScript-Equality-Table/.
Use Symbols as Keys in WeakMap
WeakMap is very similar to Map, but the difference is that its keys can only be objects or symbols, which are stored as weak references.
Why? Because the keys of a WeakMap must be garbage collectable. Most primitive data types can be freely created and have no lifecycle, so they can’t be used as keys. Objects and non-registered symbols can be used as keys because they can be garbage collected — MDN- WeakMap.
This feature means that if there are no other references to the object in memory except for the key, JavaScript engine can perform garbage collection on the object when needed.
|
|
So, what is the use of a WeakMap? Given its characteristics, it can be inferred that WeakMap can be used for custom caching and detecting memory leaks.
By using objects as keys, you can associate cached values with specific objects. When the object is garbage collected, the corresponding WeakMap entry will be automatically deleted, immediately clearing the cache.
In ES14, it has become possible to use symbols as keys in WeakMap, which can make the role of key-value pairs in WeakMap more clear. Because the only primitive type that can be used as keys in WeakMap is the symbol, the symbol guarantees that the key is unique and cannot be recreated.
|
|
Functional Programming
Since 2015, JavaScript versions have been updated, and this year (2023 ES14) is no exception.
The biggest update in ES14 is that many extra array methods have been added, or complementary methods that don’t cause mutation have been added to the existing array methods. That means they’ll create new arrays based on the original ones rather than directly modifying the original arrays.
The new complementary methods are:
Array.sort() -> Array.toSorted()
Array.splice() -> Array.toSpliced()
Array.reverse() -> Array.toReversed()
The new array methods are:
Array with()
Array.findLast()
Array.findLastIndex()
The key theme of this year is Simpler Functional Programming (fp) and Immutability.
|
|