Создание сайтов в Москве. Записи и кортежи: новые неизменяемые типы данных JavaScript

Записи и кортежи — это новые неизменяемые типы данных JavaScript, которые сейчас находятся на втором этапе процесса утверждения стандартов TC39. Они могут быть изменены и в настоящее время недоступны ни в одном браузере или среде выполнения, но рабочие реализации должны появиться в течение следующего года. Они помогают решить пару запутанных головоломок, с которыми сталкиваются кодеры...

Постоянные изменения

Профессиональные программисты JavaScript скажут вам, что присваивание переменных с помощью const— это лучшая практика, где это возможно. Это делает переменные неизменяемыми. Значения нельзя изменить, поэтому у вас будет меньше проблем.

К сожалению, constделает неизменяемыми только примитивные значения (String, Number, BigInt, Boolean, Symbol и т. д undefined.). Вы не можете переназначить массив или объект, но можно изменить содержащиеся в них значения и свойства. Например:

// array constant

const myArray = [1, 2, 3];

// change array values

myArray[0] = 99;

myArray.push (42) ;

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

myArray = 'change’; // ERROR!

Аналогично для объектов:

// object constant

const myObj = { a: 1, b: 2, c: 3 }

// change object properties

myObj.a = 99;

myObj.d = 42;

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

myObj = 'change’; // ERROR!

Метод Object.freeze () может помочь, но к непосредственным дочерним свойствам объекта применяется только неглубокая заморозка:

const myObj = { a: 1, b: 2, c: { v: 3 } }

Object.freeze (myObj) ;

myObj.a = 99; // silently ignored

myObj.c.v = 99; // works fine

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

Поэтому трудно гарантировать, что функция не изменит преднамеренно или случайно значения, хранящиеся в массиве или объекте. Разработчики должны либо надеяться на лучшее, либо передавать клонированную версию переменной — (что имеет свои проблемы).

Эквивалентное неравенство

Дальнейший хаос может возникнуть, когда разработчики попытаются, казалось бы, разумными сравнениями объектов или массивов:

const str = 'my string’;

console.log (str === 'mystring’) ; // true

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

Сравнивать по значению можно только примитивные типы. Объекты и массивы передаются и сравниваются по ссылке. Две переменные будут эквивалентны, только если они указывают на один и тот же элемент в памяти:

const a = [1, 2];

const b = a;

b.push (3) ;

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

// original array has changed

console.log (a) ; // [1, 2, 3]

Для глубокого сравнения двух объектов или массивов требуется функция рекурсивного сравнения для оценки каждого значения по очереди. Даже в этом случае вы можете столкнуться с проблемами с такими типами, как даты или функции, которые могут храниться по-разному.

Кортежи: неизменяемые структуры данных, подобные массивам

Кортежи — это глубоко неизменяемые структуры данных, подобные массивам. По сути, это составные примитивные типы, идентифицируемые #модификатором перед синтаксисом обычного массива:

// new tuples

const t1 = #[1, 2, 3];

const t2 = #[1, 2, #[3, 4]];

В качестве альтернативы новый Tuple.from () метод может создать кортеж из массива:

// new tuple from an array

const t3 = Tuple.from ([1, 2, 3]) ;

В отличие от стандартных массивов кортежи должны удовлетворять следующим требованиям:

В них не должно быть отверстий с неустановленными значениями. Например, #[1, 4]является недействительным.

Они должны устанавливать только примитивы, другие кортежи или записи. Такие типы, как массивы, объекты или функции, не разрешены:

const t4 = #[ new Date () ]; // ERROR (sets an object)

const t5 = #[1, 2, [3, 4]]; // ERROR (sets an array)

Поскольку кортежи являются примитивами, их можно глубоко сравнивать по значению с другими кортежами:

const t6 = #[1, 2];

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

Обратите внимание, что сравнения с использованием менее строгого ==оператора возможны, если кортеж содержит одно значение. Например:

const t7 = #[99];

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

console.log (t7 == 99) ; // true

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

// tuple cannot be compared to an array

console.log (t7 == [99]) ; // false

Записи: неизменяемые объектно-подобные структуры данных

Записи — это глубоко неизменяемые объектно-подобные структуры данных. Опять же, это составные примитивные типы, идентифицируемые #модификатором перед синтаксисом обычного объекта:

// new records

const r1 = #{ a: 1, b: 2 };

const r2 = #{

a: 1,

b: #{ c: 2 }, // child record

d: #[ 3, 4 ] // child tuple

};

Кроме того, новый Record () конструктор может создать запись из объекта:

// new record from an object

// #{ a: 1, b: 2 }

const r3 = Record ({ a: 1, b: 2 }) ;

Или Record.fromEntries () метод может создать запись из серии пар значений массива или кортежа:

// new record from array of name-values

// #{ a: 1, b: 2 }

const r4 = Record.fromEntries ([

['a’, 1],

['b’, 2]

]) ;

В отличие от стандартных объектов, записи должны соответствовать следующим требованиям:

Они должны использовать строковые имена свойств. Например, #{ Symbol (): 1 }является недействительным.

Они должны устанавливать значения только с использованием примитивов, других кортежей или записей. Такие типы, как массивы, объекты или функции, не разрешены:

const r5 = #{ 'd’: new Date () }; // ERROR (sets an object)

const r6 = #{ a: 1, b: { c: 2 } }; // ERROR (sets an object)

Записи можно глубоко сравнивать с другими записями, и порядок свойств не имеет значения:

const r7 = #{ a: 1, b: 2 };

console.log (r7 === #{ b: 2, a: 1 }) ; // true

Записи можно сравнивать только с другими записями, поэтому использование оператора ==or ===не имеет значения. Однако можно извлечь объект keys () и values () для конкретных сравнений. Например:

const r8 = #{ a: 99 };

console.log (Object.values (r8) == 99) ; // true

Неизменяемые обновления

Кортежи и записи могут звучать как сложные термины информатики, но они, наконец, позволят надежное неизменяемое хранилище данных и сравнения в JavaScript. Вы можете опробовать их сегодня на этой игровой площадке или с этим полифиллом, но имейте в виду, что предлагаемая реализация может измениться в ближайшие месяцы.

Делитесь нашими материалами с друзьями!

 

 

Заказать разработку сайта