What are Tuples and Records in JavaScript?

What are Tuples and Records in JavaScript?

Introduction to new immutable data types in JavaScript
Ferenc Almasi β€’ Last updated 2021 September 18 β€’ Read time 4 min read
Tuples and Records are new immutable data types in JavaScript that you can use to make sure, values are kept intact. Learn how you can use the
  • twitter
  • facebook
JavaScript

Immutability is a common term that often pops up when we talk about functional programming. This is because it is one of its core principles. When we talk about immutable objects, we simply mean that once a variable has been declared, its value cannot be changed later on. For example:

Copied to clipboard! Playground
const presents = ['🎁', 'πŸ“¦', 'πŸŽ€', 'πŸ’', 'πŸŽ„'];

// --- Mutable solution ---

// we get back 🎁
// and presents will be equal to ['πŸ“¦', 'πŸŽ€', 'πŸ’', 'πŸŽ„'];
presents.shift();

// --- Immutable solution ---

// newPresents will be equal to πŸ“¦ πŸŽ€ πŸ’ πŸŽ„
// and presents will be still equal to ['🎁', 'πŸ“¦', 'πŸŽ€', 'πŸ’', 'πŸŽ„'];
const newPresents = presents.slice(1);
immutability.js

The first solution mutates the array, while the second creates a new one and leaves the original intact. In JavaScript, we don’t have real immutable objects, so we either need workarounds to implement safety nets, or worse, we have to trust people that they won’t change the values.

Now there is a new ECMAScript proposal β€” currently at stage 2, so implementation can change β€” that would introduce two new immutable data types: Tuples and Records.


Tuples

Both tuples and records have the same syntax. They can be defined by using a # prefix in front of objects and arrays, like so:

Copied to clipboard! Playground
// This is a normal array
const arr = [];

// This is a tuple
const tuple = #[];
tuple.js

When working with tuples, there are some rules you need to be aware of:

  • There cannot be holes in an array, eg.: [1, ,2] is disallowed
  • They can only contain primitives or other tuples and records
  • Supports instance methods similar to Arrays, but with a few changes

For example, operations that mutate the array are replaced with new operations that instead, return a new array. Therefore, eg.: there’s no push, instead you can use pushed that returns a new tuple with the pushed value, or with to change a value at a given index:

Copied to clipboard! Playground
const tuple = #['πŸ„', 'πŸ…', 'πŸ₯•'];

// Both returns a new tuple
tuple.pushed('πŸ₯’');  // returns #['πŸ„', 'πŸ…', 'πŸ₯•', 'πŸ₯’'];
tuple.with(0, '🌳'); // returns #['🌳', 'πŸ…', 'πŸ₯•']
tuple.js

You can also create tuples from existing arrays using Tuple.from():

Copied to clipboard!
Tuple.from(['πŸ„', 'πŸ…', 'πŸ₯•']);

// Likewise, you can turn a tuple into an ordinary array:
Array.from(tuple);
tuple.js

And of course, they are immutable and will throw an error if you try to change their value or use non-primitives:

Copied to clipboard!
const tuples = #['πŸ„', 'πŸ…', 'πŸ₯•'];

// TypeError: Callback to Tuple.prototype.map may only return primitives, Records or Tuples
tuples.map(tuple => new Button(tuple));
tuple.js

Records

Just like tuples, records are also denoted by a hash:

Copied to clipboard! Playground
// This is a regular object
const obj = { ... };

// This is a record
const record = #{
    tuple: #['πŸ„', 'πŸ…', 'πŸ₯•'] // Records can also contain tuples
};
record.js

When working with records, you also need to keep in mind some rules:

  • You cannot use the __proto__ identifier in records
  • Methods are also disallowed. Just like tuples, they can only contain primitives.

To create a new record, you also have the option to use Record, or Record.fromEntries when working with tuples:

Copied to clipboard! Playground
const record = Record({
    mushroom: 'πŸ„',
    tomato: 'πŸ…',
    carrot: 'πŸ₯•'
});

// Or
const record = Record.fromEntries(#['πŸ„', 'πŸ…', 'πŸ₯•']);
record.js

And since they are new data types, you would get β€œrecord” back when using the typeof operator:

Copied to clipboard!
typeof #{ ... } // returns "record"
typeof #[ ... ] // returns "tuple"
types.js
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScriptinfo Remove ads

Conclusion

Other than the mentioned examples above, you can use both records and tuples in functions or loops just as you normally would with regular objects.

If you want immutability right now, the easiest way is to use Immutable-js. You can also achieve partial immutability with Object.freeze, however, it only freezes immediate children. Therefore, you can still change deeply nested properties:

Copied to clipboard! Playground
const obj = Object.freeze({
    a: 1,
    b: {
        c: 2
    }
});

// βœ… Won't work
obj.a = 10;

// ❌ Will be changed to 20
obj.b.c = 20;
freeze.js

And of course, you can also use it with Babel with the plugin-syntax-record-and-tuple plugin.

Have you already worked with Tuples and Records? Let us know your thoughts about them in the comments below! Thank you for reading through, happy coding!

  • twitter
  • facebook
JavaScript
Did you find this page helpful?
πŸ“š More Webtips
Mentoring

Rocket Launch Your Career

Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies:

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.