If you have a Python background, you must have come across one of the four main built-in data types called Tuples used to store multiple items in a single variable. Previously, we didn’t have tuples in JavaScript, and programmers had to use various methods like array destructuring to play the role of tuples. But that was before the ECMAScript proposal (by Robin Ricard and Rick Button) that introduced two new compound primitive values in JavaScript:

  • Records
  • Tuples

This post will primarily focus on the latter – JavaScript tuples.

In JavaScript, tuples are a bit like arrays since we use square brackets to define them and can also use various array methods. However, unlike arrays, they have a pre-defined length, and the types of data in a tuple are fixed once we have initialized it. In other words, a tuple in JavaScript is a typed array.

In this post, we will have an in-depth look at JavaScript Tuples and how to use them in our applications. Let’s dive in.

Support for Tuples

As stated above, Tuples are still a new primitive type in JavaScript introduced by the ECMAScript proposal. This proposal is currently in Stage 2 at the moment of this writing, which means people have looked at it and seen it’s a topic worth debating. At this point, developers also try to figure out the syntax and how the tuples would work. Unfortunately, Tuples won’t be introduced into browsers and Javascript frameworks like NodeJS until they reach Stage 3 (Candidate) or Stage 4.

Using Polyfill and Playground

Since we are still in Stage 2, we can use tuples in our applications only with Babel by using this polyfill. However, if you simply want to practice using Records and tuples without the hassle of setting up the environment, feel free to use the easy-to-use REPL – Rick Button – Tuple and Record playground. We will use this playground for this particular post.

Creating a Tuple in JavaScript

Tuples introduced a new primitive type in JavaScript, which essentially follows the array syntax. There is only one difference. When declaring a tuple, you must prefix the square brackets with a ‘#’ (hash) symbol. Look at the code below, which shows the difference between an array and a tuple.

let myArray = [12, 23, "yellow"] //this is an Array 

let myTuple = #[4, 5, "black"] // this is a Tuple. You can see the '#' in front of the square brackets. 

log("isArray", Array.isArray(myArray)) 
//Returns [“isArray”, true] 

log("isTuple", Tuple.isTuple(myTuple)) 
//Returns [“isTuple”, true]

As you can see in the code snippet above, the syntax of tuples is quite similar to that of arrays, with the only difference being the ‘#’ sign.

You will also notice that although we said tuples are primitive data types, we are using the Tuple.isTuple to check the type of our tuple variable instead of the typeof() keyword. That’s because typeof() is still an unsupported feature in the Babel polyfill we are using and will return an incorrect value.

Tuples are Primitives

JavaScript stores data either as ‘primitive types’ or ‘reference types.’ Primitive types are simple atomic pieces that are always saved and accessed by the variable’s value and not as a reference to an object. There are six main primitive types in JavaScript: undefined, null, boolean, symbol, string, and number. With the ECMAScript proposal, we will now have more primitives, including records and tuples.

Therefore, when we use the typeof keyword to check the type of our tuple variable, it should return a tuple as shown in the code snippet below.

typeof #['a', 'b'] 
//returns 'tuple' 

let myTuple = #["Bob","Jane"] 
typeof(myTuple) 
//returns 'tuple'

Reference types are not simple atomic values, but objects made up of multiple properties assigned to them. They are stored as a reference in memory and not as independent values assigned to variables. The three main reference types in JavaScript are arrays, objects, and functions.

Tuples are Deeply Immutable

In many programming languages, we have both mutable and immutable values. Mutable values are those that can be changed or a new property can be added to them. On the other hand, immutable values in JavaScript cannot be changed or have anything added to them. They can only be reassigned. All primitive types in JavaScript are immutable. Let’s understand this by looking at strings and arrays.


//We will create two String variables (nameOne and nameTwo)



let nameOne = "John"; 
let nameTwo = nameOne; 

console.log(nameOne) 
//returns 'John' 
console.log(nameTwo) 
//returns 'John' 

 
//Here we are re-assigning the nameTwo variable to ‘Janedoe’
nameTwo = "Janedoe"

 
//When we log the output of the two variables, only nameTwo changed.

console.log(nameOne) 
//returns 'John' 
console.log(nameTwo) 
//returns 'Janedoe'

From the code snippet above, you notice that after we re-assigned the variable “nameTwo,” the value of variable “nameOne” did not change and instead a new string was created. Now let’s look at arrays that are reference types and are mutable.


let arrayOne = [12, 13, 14] 
Let arrayTwo = arrayOne 

console.log(arrayOne); 
//returns [12,13,14] 
console.log(arrayTwo) 
//returns [12,13,14] 

//Let's re-assign an index in arrayTwo


arrayTwo[0] = "yellow" 
console.log(arrayOne); 
//returns ["Yellow",13,14] 
console.log(arrayTwo) 
//returns ["Yellow",13,14]

From the code snippet, you notice that when we re-assigned the index[0] in arrayTwo, the values in arrayOne also changed since the two variables were referencing one object.

So, why are tuples deeply immutable? That’s mainly because tuples by themselves are immutable and they can only hold primitive types, other tuples or records (which are also immutable). A tuple cannot hold any reference types, such as arrays or objects. However, the opposite is true. You can use an array or object to hold a tuple.

// This is Okay 
const tupleOne = #[10, 20, "Johndoe",] 

//ERROR: Sets an Array  
const tupleTwo = #[10,22,"Janedoe",[12,4,5]]

 
//ERROR: Sets an Object

 
const tupleThree = [new Date()]

 
//This is Okay. 

 
const arrayOne = [12, 13, 14, #[12, 13, “Yellow”]]

 
console.log(arrayOne[3])

 
//returns tuple {12,13,”Yellow”}

 
//Error: Tuples can’t be changed at any level

 
const tupleOne[0] = 23

Lastly, tuples cannot have holes of unset values.

//This will raise an Error: Unexpected token ','  
Let tupOne = #[2,,,"Green",5]

Comparing by Value

If there is one hurdle that most newbie JavaScript developers face is comparing reference types. Let’s look at the code below which tries to compare arrays and objects.

//Compare Objects 
console.log({a:12, b:24} === {a:12,b:24}) 
//returns false 

//Compare Arrays 
console.log([12,13,14]===[12,13,14]) 
//returns false

Why are we getting a ‘ False ’ yet the array and the object have the same values? Reference types like Arrays and Objects in JavaScript are compared by the reference or address in memory where the value is stored. And of course, we cannot store two different variables in the same memory address.

Unlike arrays, tuples are compared by their values.

console.log(#[12,13,14] === #[12,13,14]) 
//returns true 
console.log(#[12,13,15] === #[20,30,40]) 
//returns false

Convert Arrays to Tuples

You can use the Tuple.from() method to create a tuple from an existing array.

const arrayOne = [12,13,14] 
const tupleOne = Tuple.from(arrayOne) 

const tupleTwo = Tuple.from([12,24,35])

Caveat: However, there is a catch! If any value in the array is of non-primitive type, you will get an error. That’s because tuples in JavaScript can only hold primitive types. See the code snippet below.


const arrayOne = [12,13,[25,34]] 

//This will raise an Error 
const tupOne = Tuple.from(arrayOne)

 
//This will raise Error
const tupTwo = Tuple.from([1,2,[“a”,”b”]])

Convert Tuples to Arrays

Likewise, you can use the Array.from() method to convert tuples to arrays.

let tupOne = #[12,13] 

log(Array.from(tupOne)) 
//returns [12,13]

JSON and Tuples

The JSON.stringify() method is used to convert arrays and objects to JSON strings and treats tuples like arrays. See the code snippet below.

const tupOne = #[12,13,#[12,13]] 
const a = JSON.stringify(tupOne) 
console.log(a) 
//returns "[12,13,[12,13]]" 

const tupTwo = #[12,13] 
console.log(tupTwo) 
//returns # "[12,13]"

Conclusion

That’s it! Up to this point, I believe you now have a good understanding of what tuples are in JavaScript and how you can use them in your program. Other than the few examples we have looked at above, you can use tuples in loops and functions as you would with arrays. As of writing this post, tuples are still a new feature and not widely supported. You will need the Babel polyfill to use them.

Have you already worked with tuples?

Please, let us know your thoughts by replying on Twitter of Become A Better Programmer.

Author