Essential Standard JavaScript Objects for Developers
Written on
Chapter 1: Understanding JavaScript's Core Objects
In the realm of programming languages, most come equipped with a defined syntax, diverse data types, and a standard library of APIs. These libraries provide pre-built features that enable developers to tackle real-world software challenges. For instance, JavaScript includes the Array object as part of its standard library, allowing for effective manipulation of array structures. While most developers are familiar with the Array object and its methods, there are several newer built-in objects that not all developers utilize effectively.
Since the introduction of ES5 in 2009, ECMAScript has encouraged JavaScript engines to incorporate more standard objects, aiding developers in crafting manageable and efficient code. Some of these newer objects have even enhanced traditional JavaScript coding styles. For example, the ES6 Promise object has made it easier for developers to write clean asynchronous code without relying on callbacks. Additionally, some ECMAScript objects have empowered developers to create efficient JavaScript applications with less code, such as utilizing typed arrays for binary data handling instead of manual implementations.
This article will delve into specific standard JavaScript objects that can help you write cleaner, more efficient code. By leveraging these objects and their methods, you can create high-quality, modern software systems without resorting to inefficient workarounds or unnecessary third-party libraries.
Section 1.1: Efficient Binary Data Handling with ArrayBuffer
Historically, web developers relied heavily on server-side computation for data processing, so handling byte-level data was not a priority for client-side JavaScript. However, as web technologies have advanced and hardware capabilities have improved, developers have begun to leverage client-side processing for data manipulation. Previously, developers needed to either create custom implementations or rely on libraries for binary data handling, which were often inefficient as they used basic JavaScript elements like strings, numbers, or traditional arrays with bitwise operations.
Today, the ECMAScript standard provides robust, native support for efficient binary data processing through the ArrayBuffer and various typed array objects. The ArrayBuffer object allows you to define a generic raw byte buffer based on a specified byte length:
const ab = new ArrayBuffer(2);
console.log(ab.byteLength); // 2
The code snippet above creates a 2-byte buffer. However, to store binary data, you must create a typed array that references the ArrayBuffer. For instance, the following code creates a typed array with one-byte elements:
const arr = new Uint8Array(ab);
arr[0] = 65;
arr[1] = 200; // min: 0, max: 255
console.log(arr.reduce((str, byte) => str + byte.toString(2).padStart(8, '0') + ' ', ''));
// 01000001 11001000
In this example, the Uint8Array object is utilized to access the ArrayBuffer, allowing for two typed array elements. To store unsigned values greater than 255, consider using Uint16Array, as shown below:
const arr = new Uint16Array(ab);
arr[0] = 256; // min: 0, max: 65535
console.log(arr.reduce((str, byte) => str + byte.toString(2).padStart(16, '0') + ' ', ''));
// 0000000100000000
This configuration allows for only one element since the element size is two bytes, which equals the size of the ArrayBuffer. For further details, refer to the official MDN documentation on supported typed array objects. To analyze the memory structure allocated for ArrayBuffers, Chrome DevTools can be employed.
Section 1.2: Utilizing Internationalization Features with Intl
Internationalization (i18n) refers to features that assist developers in converting in-source elements into locale-specific formats, such as dates, numbers, or string lists. JavaScript offers built-in internationalization capabilities through the Intl namespace, enabling developers to create applications that cater to diverse languages without needing third-party libraries.
For example, the Intl.DateTimeFormat object can format a JavaScript date object into a readable string based on a specified locale:
const date = new Date(Date.UTC(2024, 10, 12));
// US English: mm/dd/yyyy
console.log(new Intl.DateTimeFormat('en-US').format(date));
// 11/12/2024
// British English: dd/mm/yyyy
console.log(new Intl.DateTimeFormat('en-GB').format(date));
// 12/11/2024
The Intl.NumberFormat object is helpful for formatting numbers according to different locales, accommodating decimal points, units, percentages, and currencies:
console.log(Intl.NumberFormat('en').format(20000));
// 20,000
console.log(Intl.NumberFormat('en', {
style: 'unit',
unit: 'meter'
}).format(20));
// 20 m
console.log(Intl.NumberFormat('en', {
style: 'percent'}).format(0.2));
// 20%
console.log(Intl.NumberFormat('en', {
style: 'currency',
currency: 'USD'
}).format(10.25));
// $10.25
For string comparisons sensitive to language, the Intl.Collator object can be employed with the sort() and toSorted() methods:
const arr = ['ä', 'v', 'ü', 's', 'a'];
console.log(arr.toSorted(new Intl.Collator('de').compare));
// ["a", "ä", "s", "ü", "v"]
In cases where arrays need to be converted into formatted strings with connectors, the Intl.ListFormat object is beneficial:
const arr = ['Apple', 'Samsung', 'OnePlus'];
console.log(new Intl.ListFormat('en-US').format(arr));
// Apple, Samsung, and OnePlus
console.log(new Intl.ListFormat('de').format(arr));
// Apple, Samsung und OnePlus
console.log(new Intl.ListFormat('en-US', {
type: 'disjunction'}).format(arr));
// Apple, Samsung, or OnePlus
Additionally, the Intl.PluralRules object aids in generating grammatically accurate sentences containing numbers:
const rl = new Intl.PluralRules('en');
function getSentence(n = 0) {
const sentences = {
one: ${n} item was selected,other: ${n} items were selected
};
return sentences[rl.select(n)];
}
console.log(getSentence(0)); // 0 items were selected
console.log(getSentence(1)); // 1 item was selected
console.log(getSentence(2)); // 2 items were selected
The Intl namespace also provides RelativeTimeFormat and Segmenter for locale-sensitive relative time formatting and text segmentation.
Chapter 2: Advanced Data Structures
In programming projects, various data structures are essential. While arrays are commonly used, other structures like maps and sets are equally important. Previously, developers relied on generic objects as maps and used arrays to implement set characteristics. However, JavaScript now offers dedicated Map and Set objects for these purposes.
The Map object allows for key-value data manipulation with various efficient methods:
const m = new Map();
m.set('Pen', 1);
m.set('Book', 2);
for(let [k, v] of m) {
console.log(${k}:t$${v});}
The Set object facilitates the creation of native set structures:
const s = new Set([1, 2, 10]);
s.delete(2);
s.add(20);
console.log(s); // {1, 10, 20}
Currently, the TC39 group has proposed set operations for the Set object, including union, difference, and intersection methods. However, only the Apple Safari browser has implemented these features publicly, necessitating patience until other browsers adopt them.
Both the Map and Set objects have weak counterparts, WeakMap and WeakSet, designed for storing garbage-collectable, weakly-referenced objects. This functionality allows for automatic removal of unreferenced elements.
Mastering data structures and algorithms is crucial for advancing your software development career, as discussed in the following section.
The next chapter focuses on addressing the issues associated with JavaScript's single number type by introducing the BigInt object.