Home >Web Front-end >JS Tutorial >Records and Tuples: JavaScript's New Immutable Data Types

Records and Tuples: JavaScript's New Immutable Data Types

Christopher Nolan
Christopher NolanOriginal
2025-02-12 08:25:09233browse

Records and Tuples: JavaScript's New Immutable Data Types

JavaScript records and tuples: the future of immutable data structures

JavaScript is about to usher in two new immutable data types: records and tuples. They are currently in Phase 2 of the TC39 standard approval process and are still being improved and are not available in any browser or runtime environment, but implementation versions are expected to be available within next year. They are designed to solve some of the tough problems developers face when using arrays and objects.

Key Points

  • Records and tuples are new immutable data types under development in JavaScript and are expected to be available within next year. They are designed to solve challenges faced by developers, such as ensuring that functions do not intentionally or unintentionally change values ​​saved in arrays or objects.
  • Tuples are array-like data structures with immutable depth. They cannot have unset values, they can only set basic types, other tuples, or records. Tuples are primitive types, so you can compare in depth with other tuples by value.
  • Records are data structures similar to objects with immutable depth. They must use string attribute names and can only set values ​​with primitive types, other tuples, or records. Records can be compared in depth with other records, and the order of attributes is irrelevant.

Limitations of const

Experienced JavaScript developers know that using const to declare variables is best practice. It makes variables immutable. The value cannot be changed, so you need to deal with fewer issues.

Unfortunately, const can only make the base values ​​immutable (strings, numbers, BigInt, booleans, symbols, and undefined). You cannot reassign arrays or objects, but the values ​​and properties they contain are can be modified. For example:

The same is true for the
<code class="language-javascript">// 数组常量
const myArray = [1, 2, 3];

// 更改数组值
myArray[0] = 99;
myArray.push(42);

console.log(myArray); // [ 99, 2, 3, 42 ]

myArray = 'change'; // 错误!</code>
Objects:

The
<code class="language-javascript">// 对象常量
const myObj = { a: 1, b: 2, c: 3 };

// 更改对象属性
myObj.a = 99;
myObj.d = 42;

console.log(myObj); // { a: 99, b: 2, c: 3, d: 42 }

myObj = 'change'; // 错误!</code>

method can help, but it only applies shallow freeze to the object's direct child properties: Object.freeze()

<code class="language-javascript">const myObj = { a: 1, b: 2, c: { v: 3 } };
Object.freeze(myObj);

myObj.a = 99; // 静默忽略
myObj.c.v = 99; // 可以正常工作

console.log(myObj); // { a: 1, b: 2, c: { v: 99 } }</code>
Therefore, it is difficult to ensure that functions do not intentionally or unintentionally change the values ​​saved in arrays or objects. Developers either leave things alone or pass cloned versions of variables—(this also has its own challenges).

Inconsistent comparison

More confusion may occur when developers try to make seemingly reasonable object or array comparisons:

<code class="language-javascript">const str = 'my string';
console.log(str === 'mystring');  // false

const num = 123;
console.log(num === 123);         // true

const arr = [1, 2, 3];
console.log(arr === [1, 2, 3]);   // false

const obj = { a: 1 };
console.log(obj === { a: 1 });    // false</code>
Only the basic types can be compared by value. Objects and arrays are passed and compared by reference

. Only when two variables point to the same item in memory do they equally:

Deep comparison of two objects or arrays requires a recursive comparison function to evaluate each value in turn. Even then, you may have problems with types like dates or functions that may be stored in different ways.
<code class="language-javascript">const a = [1, 2];

const b = a;
b.push(3);

console.log(a === b); // true

// 原始数组已更改
console.log(a); // [1, 2, 3]</code>

Tuple: Immutable array-like data structure

Tuples are array-like data structures with immutable depth. They are actually compound primitive types, identified with the # modifier before normal array syntax:

<code class="language-javascript">// 数组常量
const myArray = [1, 2, 3];

// 更改数组值
myArray[0] = 99;
myArray.push(42);

console.log(myArray); // [ 99, 2, 3, 42 ]

myArray = 'change'; // 错误!</code>

Or, the new Tuple.from() method can create a tuple from an array:

<code class="language-javascript">// 对象常量
const myObj = { a: 1, b: 2, c: 3 };

// 更改对象属性
myObj.a = 99;
myObj.d = 42;

console.log(myObj); // { a: 99, b: 2, c: 3, d: 42 }

myObj = 'change'; // 错误!</code>

Unlike standard arrays, tuples must meet the following requirements:

  1. They cannot have empty spaces with a value of undefined. For example, #[1,,,4] is invalid.
  2. They can only set basic types, other tuples, or records. Arrays, objects, or functions are not allowed to be used:
<code class="language-javascript">const myObj = { a: 1, b: 2, c: { v: 3 } };
Object.freeze(myObj);

myObj.a = 99; // 静默忽略
myObj.c.v = 99; // 可以正常工作

console.log(myObj); // { a: 1, b: 2, c: { v: 99 } }</code>

Since tuples are basic types, you can compare depth with other tuples by value:

<code class="language-javascript">const str = 'my string';
console.log(str === 'mystring');  // false

const num = 123;
console.log(num === 123);         // true

const arr = [1, 2, 3];
console.log(arr === [1, 2, 3]);   // false

const obj = { a: 1 };
console.log(obj === { a: 1 });    // false</code>

Note that if the tuple contains a single value, you can use the looser == operator for comparison. For example:

<code class="language-javascript">const a = [1, 2];

const b = a;
b.push(3);

console.log(a === b); // true

// 原始数组已更改
console.log(a); // [1, 2, 3]</code>

Record: Immutable object-like data structure

Records are data structures similar to objects with immutable depth. Again, they are compound primitive types, identified using the # modifier before the normal object syntax:

<code class="language-javascript">// 新的元组
const t1 = #[1, 2, 3];
const t2 = #[1, 2, #[3, 4]];</code>

Or, the new Record() constructor can create a record from an object:

<code class="language-javascript">// 从数组创建新的元组
const t3 = Tuple.from([1, 2, 3]);</code>

or Record.fromEntries() method can create a record from a series of array or tuple key-value pairs:

<code class="language-javascript">const t4 = #[new Date()]; // 错误(设置一个对象)
const t5 = #[1, 2, [3, 4]]; // 错误(设置一个数组)</code>

Unlike standard objects, records must meet the following requirements:

  1. They must use string attribute names. For example, #{ Symbol(): 1 } is invalid.
  2. They can only set values ​​using primitive types, other tuples, or records. Arrays, objects, or functions are not allowed to be used:
<code class="language-javascript">const t6 = #[1, 2];

console.log(t6 === #[1, 2]); // true</code>

Records can be compared in depth with other records, and the order of attributes is irrelevant:

<code class="language-javascript">const t7 = #[99];

console.log(t7 == #[99]); // true
console.log(t7 == 99);    // true
console.log(t7 == '99');  // true

// 元组不能与数组比较
console.log(t7 == [99]);  // false</code>

records can only be compared with other records, so there is no difference between using the == or === operators. However, Object.keys() and Object.values() can be extracted for specific comparisons. For example:

<code class="language-javascript">// 新的记录
const r1 = #{ a: 1, b: 2 };
const r2 = #{
  a: 1,
  b: #{ c: 2 }, // 子记录
  d: #[3, 4]  // 子元组
};</code>

Immutable update

Tuples and records sound like complex computer science terms, but they ultimately allow for powerful immutable data storage and comparison in JavaScript.

Records and Tuples in JavaScript FAQ

What is a record in JavaScript? Records in JavaScript are an object-like structure introduced in ECMAScript 2022 (ES12). It is designed to represent data with named properties and is immutable by default, so it is suitable for use as a data structure where values ​​are not changed after creation.

How is the difference between records and ordinary JavaScript objects? Unlike normal objects, records in JavaScript are immutable by default, and once set, their properties cannot be modified. The records are also more predictable and have stricter structures, so they are suitable for use as data containers.

What are tuples in JavaScript? Tuples in JavaScript are an ordered collection of elements, where each element can be of a different type. Tuples are immutable and fixed in length, providing a way to represent and process fixed number of values ​​in a particular order.

How do records and tuples enhance the readability and maintainability of your code? Records and tuples can enhance the readability of code by providing a more declarative and structured way to represent data. The immutability aspect also helps prevent accidental modifications, thereby improving the maintainability of the code.

Are there any performance considerations when using records and tuples? Records and tuples act as immutable data structures, which can improve performance in some cases. However, browser support and specific use cases must be considered, as performance impacts may vary depending on implementation details of the JavaScript runtime.

How to provide polyfill for records and tuples in an environment without native support? As of my last update, records and tuples can be simulated in environments without native support using polyfill or translator. However, it is recommended to keep up to date with updates to JavaScript standards and tools as the ecosystem continues to evolve.

The above is the detailed content of Records and Tuples: JavaScript's New Immutable Data Types. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn