Destructuring assignment

The two most used data structures in JavaScript are Object and Array .

  • Objects allow us to create a single entity that stores data items by key.
  • Arrays allow us to gather data items into an ordered list.

However, when we pass these to a function, we may not need all of it. The function might only require certain elements or properties.

Destructuring assignment is a special syntax that allows us to “unpack” arrays or objects into a bunch of variables, as sometimes that’s more convenient.

Destructuring also works well with complex functions that have a lot of parameters, default values, and so on. Soon we’ll see that.

Array destructuring

Here’s an example of how an array is destructured into variables:

Now we can work with variables instead of array members.

It looks great when combined with split or other array-returning methods:

As you can see, the syntax is simple. There are several peculiar details though. Let’s see more examples to understand it better.

It’s called “destructuring assignment,” because it “destructurizes” by copying items into variables. However, the array itself is not modified.

It’s just a shorter way to write:

Unwanted elements of the array can also be thrown away via an extra comma:

In the code above, the second element of the array is skipped, the third one is assigned to title , and the rest of the array items are also skipped (as there are no variables for them).

…Actually, we can use it with any iterable, not only arrays:

That works, because internally a destructuring assignment works by iterating over the right value. It’s a kind of syntax sugar for calling for..of over the value to the right of = and assigning the values.

We can use any “assignables” on the left side.

For instance, an object property:

In the previous chapter, we saw the Object.entries(obj) method.

We can use it with destructuring to loop over the keys-and-values of an object:

The similar code for a Map is simpler, as it’s iterable:

There’s a well-known trick for swapping values of two variables using a destructuring assignment:

Here we create a temporary array of two variables and immediately destructure it in swapped order.

We can swap more than two variables this way.

The rest ‘…’

Usually, if the array is longer than the list at the left, the “extra” items are omitted.

For example, here only two items are taken, and the rest is just ignored:

If we’d like also to gather all that follows – we can add one more parameter that gets “the rest” using three dots "..." :

The value of rest is the array of the remaining array elements.

We can use any other variable name in place of rest , just make sure it has three dots before it and goes last in the destructuring assignment.

Default values

If the array is shorter than the list of variables on the left, there will be no errors. Absent values are considered undefined:

If we want a “default” value to replace the missing one, we can provide it using = :

Default values can be more complex expressions or even function calls. They are evaluated only if the value is not provided.

For instance, here we use the prompt function for two defaults:

Please note: the prompt will run only for the missing value ( surname ).

Object destructuring

The destructuring assignment also works with objects.

The basic syntax is:

We should have an existing object on the right side, that we want to split into variables. The left side contains an object-like “pattern” for corresponding properties. In the simplest case, that’s a list of variable names in {...} .

For instance:

Properties options.title , options.width and options.height are assigned to the corresponding variables.

The order does not matter. This works too:

The pattern on the left side may be more complex and specify the mapping between properties and variables.

If we want to assign a property to a variable with another name, for instance, make options.width go into the variable named w , then we can set the variable name using a colon:

The colon shows “what : goes where”. In the example above the property width goes to w , property height goes to h , and title is assigned to the same name.

For potentially missing properties we can set default values using "=" , like this:

Just like with arrays or function parameters, default values can be any expressions or even function calls. They will be evaluated if the value is not provided.

In the code below prompt asks for width , but not for title :

We also can combine both the colon and equality:

If we have a complex object with many properties, we can extract only what we need:

The rest pattern “…”

What if the object has more properties than we have variables? Can we take some and then assign the “rest” somewhere?

We can use the rest pattern, just like we did with arrays. It’s not supported by some older browsers (IE, use Babel to polyfill it), but works in modern ones.

It looks like this:

In the examples above variables were declared right in the assignment: let {…} = {…} . Of course, we could use existing variables too, without let . But there’s a catch.

This won’t work:

The problem is that JavaScript treats {...} in the main code flow (not inside another expression) as a code block. Such code blocks can be used to group statements, like this:

So here JavaScript assumes that we have a code block, that’s why there’s an error. We want destructuring instead.

To show JavaScript that it’s not a code block, we can wrap the expression in parentheses (...) :

Nested destructuring

If an object or an array contains other nested objects and arrays, we can use more complex left-side patterns to extract deeper portions.

In the code below options has another object in the property size and an array in the property items . The pattern on the left side of the assignment has the same structure to extract values from them:

All properties of options object except extra which is absent in the left part, are assigned to corresponding variables:

Finally, we have width , height , item1 , item2 and title from the default value.

Note that there are no variables for size and items , as we take their content instead.

Smart function parameters

There are times when a function has many parameters, most of which are optional. That’s especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, an item list and so on.

Here’s a bad way to write such a function:

In real-life, the problem is how to remember the order of arguments. Usually, IDEs try to help us, especially if the code is well-documented, but still… Another problem is how to call a function when most parameters are ok by default.

That’s ugly. And becomes unreadable when we deal with more parameters.

Destructuring comes to the rescue!

We can pass parameters as an object, and the function immediately destructurizes them into variables:

We can also use more complex destructuring with nested objects and colon mappings:

The full syntax is the same as for a destructuring assignment:

Then, for an object of parameters, there will be a variable varName for the property incomingProperty , with defaultValue by default.

Please note that such destructuring assumes that showMenu() does have an argument. If we want all values by default, then we should specify an empty object:

We can fix this by making {} the default value for the whole object of parameters:

In the code above, the whole arguments object is {} by default, so there’s always something to destructurize.

Destructuring assignment allows for instantly mapping an object or array onto many variables.

The full object syntax:

This means that property prop should go into the variable varName and, if no such property exists, then the default value should be used.

Object properties that have no mapping are copied to the rest object.

The full array syntax:

The first item goes to item1 ; the second goes into item2 , and all the rest makes the array rest .

It’s possible to extract data from nested arrays/objects, for that the left side must have the same structure as the right one.

We have an object:

Write the destructuring assignment that reads:

  • name property into the variable name .
  • years property into the variable age .
  • isAdmin property into the variable isAdmin (false, if no such property)

Here’s an example of the values after your assignment:

The maximal salary

There is a salaries object:

Create the function topSalary(salaries) that returns the name of the top-paid person.

  • If salaries is empty, it should return null .
  • If there are multiple top-paid persons, return any of them.

P.S. Use Object.entries and destructuring to iterate over key/value pairs.

Open a sandbox with tests.

Open the solution with tests in a sandbox.

  • If you have suggestions what to improve - please submit a GitHub issue or a pull request instead of commenting.
  • If you can't understand something in the article – please elaborate.
  • To insert few words of code, use the <code> tag, for several lines – wrap them in <pre> tag, for more than 10 lines – use a sandbox ( plnkr , jsbin , codepen …)

Lesson navigation

  • © 2007—2024  Ilya Kantor
  • about the project
  • terms of usage
  • privacy policy

JavaScript Destructuring Assignment

Javascript tutorial index.

Destructuring assignment in JavaScript is a powerful feature that simplifies how you extract values from arrays or properties from objects. It allows you to unpack values into distinct variables concisely and readably. In this tutorial, you'll learn the basics of destructuring assignments, including working with arrays and objects and applying them in real-world scenarios.

What is a Destructuring Assignment?

Destructuring is an expression in JavaScript that makes it feasible to unpack values from arrays or properties from objects and assign them to distinct variables. It was introduced in ES6 (ECMAScript 2015) and provides a more readable and concise way to access data.

Array Destructuring

Array destructuring allows you to assign elements of an array to separate variables. Consider an array of colors:

Without destructuring, you might access these elements like this:

With destructuring, it simplifies to:

Skipping Elements

You can skip elements using extra commas:

Default Values

Destructuring can have default values if the unpacked value is undefined :

Object Destructuring

Object destructuring works similarly but with object properties. Given an object:

Traditional approach:

Destructuring approach:

Renaming Variables

You can rename variables:

Like arrays, default values are possible:

Nested Destructuring

You can also destructure nested objects:

Practical Uses of Destructuring

Swapping variables.

Swap values easily without a temporary variable:

Function Parameter Destructuring

Function parameter destructuring allows you to unpack values directly from an object passed as a parameter. This technique is beneficial in functions where you expect an object with specific properties.

JavaScript destructuring assignment is a handy feature for writing cleaner and more readable code. It helps in extracting array elements or object properties directly into variables. Use it to simplify your code and make it more expressive.

  • Skip to main content
  • Select language
  • Skip to search
  • Destructuring assignment

Unpacking values from a regular expression match

Es2015 version, invalid javascript identifier as a property name.

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

Description

The object and array literal expressions provide an easy way to create ad hoc packages of data.

The destructuring assignment uses similar syntax, but on the left-hand side of the assignment to define what values to unpack from the sourced variable.

This capability is similar to features present in languages such as Perl and Python.

Array destructuring

Basic variable assignment, assignment separate from declaration.

A variable can be assigned its value via destructuring separate from the variable's declaration.

Default values

A variable can be assigned a default, in the case that the value unpacked from the array is undefined .

Swapping variables

Two variables values can be swapped in one destructuring expression.

Without destructuring assignment, swapping two values requires a temporary variable (or, in some low-level languages, the XOR-swap trick ).

Parsing an array returned from a function

It's always been possible to return an array from a function. Destructuring can make working with an array return value more concise.

In this example, f() returns the values [1, 2] as its output, which can be parsed in a single line with destructuring.

Ignoring some returned values

You can ignore return values that you're not interested in:

You can also ignore all returned values:

Assigning the rest of an array to a variable

When destructuring an array, you can unpack and assign the remaining part of it to a variable using the rest pattern:

Note that a SyntaxError will be thrown if a trailing comma is used on the left-hand side with a rest element:

When the regular expression exec() method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to unpack the parts out of this array easily, ignoring the full match if it is not needed.

Object destructuring

Basic assignment, assignment without declaration.

A variable can be assigned its value with destructuring separate from its declaration.

The ( .. ) around the assignment statement is required syntax when using object literal destructuring assignment without a declaration.

{a, b} = {a: 1, b: 2} is not valid stand-alone syntax, as the {a, b} on the left-hand side is considered a block and not an object literal.

However, ({a, b} = {a: 1, b: 2}) is valid, as is var {a, b} = {a: 1, b: 2}

NOTE: Your ( ..) expression needs to be preceded by a semicolon or it may be used to execute a function on the previous line.

Assigning to new variable names

A property can be unpacked from an object and assigned to a variable with a different name than the object property.

A variable can be assigned a default, in the case that the value unpacked from the object is undefined .

Setting a function parameter's default value

Es5 version, nested object and array destructuring, for of iteration and destructuring, unpacking fields from objects passed as function parameter.

This unpacks the id , displayName and firstName from the user object and prints them.

Computed object property names and destructuring

Computed property names, like on object literals , can be used with destructuring.

Rest in Object Destructuring

The Rest/Spread Properties for ECMAScript proposal (stage 3) adds the rest syntax to destructuring. Rest properties collect the remaining own enumerable property keys that are not already picked off by the destructuring pattern.

Destructuring can be used with property names that are not valid JavaScript identifiers  by providing an alternative identifer that is valid.

Specifications

Browser compatibility.

[1] Requires "Enable experimental Javascript features" to be enabled under `about:flags`

Firefox-specific notes

  • Firefox provided a non-standard language extension in JS1.7 for destructuring. This extension has been removed in Gecko 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37). See bug 1083498 .
  • Starting with Gecko 41 (Firefox 41 / Thunderbird 41 / SeaMonkey 2.38) and to comply with the ES2015 specification, parenthesized destructuring patterns, like ([a, b]) = [1, 2] or ({a, b}) = { a: 1, b: 2 } , are now considered invalid and will throw a SyntaxError . See Jeff Walden's blog post and bug 1146136 for more details.
  • Assignment operators
  • "ES6 in Depth: Destructuring" on hacks.mozilla.org

Document Tags and Contributors

  • Destructuring
  • ECMAScript 2015
  • JavaScript basics
  • JavaScript first steps
  • JavaScript building blocks
  • Introducing JavaScript objects
  • Introduction
  • Grammar and types
  • Control flow and error handling
  • Loops and iteration
  • Expressions and operators
  • Numbers and dates
  • Text formatting
  • Regular expressions
  • Indexed collections
  • Keyed collections
  • Working with objects
  • Details of the object model
  • Iterators and generators
  • Meta programming
  • A re-introduction to JavaScript
  • JavaScript data structures
  • Equality comparisons and sameness
  • Inheritance and the prototype chain
  • Strict mode
  • JavaScript typed arrays
  • Memory Management
  • Concurrency model and Event Loop
  • References:
  • ArrayBuffer
  • AsyncFunction
  • Float32Array
  • Float64Array
  • GeneratorFunction
  • InternalError
  • Intl.Collator
  • Intl.DateTimeFormat
  • Intl.NumberFormat
  • ParallelArray
  • ReferenceError
  • SIMD.Bool16x8
  • SIMD.Bool32x4
  • SIMD.Bool64x2
  • SIMD.Bool8x16
  • SIMD.Float32x4
  • SIMD.Float64x2
  • SIMD.Int16x8
  • SIMD.Int32x4
  • SIMD.Int8x16
  • SIMD.Uint16x8
  • SIMD.Uint32x4
  • SIMD.Uint8x16
  • SharedArrayBuffer
  • StopIteration
  • SyntaxError
  • Uint16Array
  • Uint32Array
  • Uint8ClampedArray
  • WebAssembly
  • decodeURI()
  • decodeURIComponent()
  • encodeURI()
  • encodeURIComponent()
  • parseFloat()
  • Arithmetic operators
  • Array comprehensions
  • Bitwise operators
  • Comma operator
  • Comparison operators
  • Conditional (ternary) Operator
  • Expression closures
  • Generator comprehensions
  • Grouping operator
  • Legacy generator function expression
  • Logical Operators
  • Object initializer
  • Operator precedence
  • Property accessors
  • Spread syntax
  • async function expression
  • class expression
  • delete operator
  • function expression
  • function* expression
  • in operator
  • new operator
  • void operator
  • Legacy generator function
  • async function
  • for each...in
  • function declaration
  • try...catch
  • Arguments object
  • Arrow functions
  • Default parameters
  • Method definitions
  • Rest parameters
  • constructor
  • element loaded from a different domain for which you violated the same-origin policy.">Error: Permission denied to access property "x"
  • InternalError: too much recursion
  • RangeError: argument is not a valid code point
  • RangeError: invalid array length
  • RangeError: invalid date
  • RangeError: precision is out of range
  • RangeError: radix must be an integer
  • RangeError: repeat count must be less than infinity
  • RangeError: repeat count must be non-negative
  • ReferenceError: "x" is not defined
  • ReferenceError: assignment to undeclared variable "x"
  • ReferenceError: deprecated caller or arguments usage
  • ReferenceError: invalid assignment left-hand side
  • ReferenceError: reference to undefined property "x"
  • SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated
  • SyntaxError: "use strict" not allowed in function with non-simple parameters
  • SyntaxError: "x" is a reserved identifier
  • SyntaxError: JSON.parse: bad parsing
  • SyntaxError: Malformed formal parameter
  • SyntaxError: Unexpected token
  • SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead
  • SyntaxError: a declaration in the head of a for-of loop can't have an initializer
  • SyntaxError: applying the 'delete' operator to an unqualified name is deprecated
  • SyntaxError: for-in loop head declarations may not have initializers
  • SyntaxError: function statement requires a name
  • SyntaxError: identifier starts immediately after numeric literal
  • SyntaxError: illegal character
  • SyntaxError: invalid regular expression flag "x"
  • SyntaxError: missing ) after argument list
  • SyntaxError: missing ) after condition
  • SyntaxError: missing : after property id
  • SyntaxError: missing ; before statement
  • SyntaxError: missing = in const declaration
  • SyntaxError: missing ] after element list
  • SyntaxError: missing formal parameter
  • SyntaxError: missing name after . operator
  • SyntaxError: missing variable name
  • SyntaxError: missing } after function body
  • SyntaxError: missing } after property list
  • SyntaxError: redeclaration of formal parameter "x"
  • SyntaxError: return not in function
  • SyntaxError: test for equality (==) mistyped as assignment (=)?
  • SyntaxError: unterminated string literal
  • TypeError: "x" has no properties
  • TypeError: "x" is (not) "y"
  • TypeError: "x" is not a constructor
  • TypeError: "x" is not a function
  • TypeError: "x" is not a non-null object
  • TypeError: "x" is read-only
  • TypeError: More arguments needed
  • TypeError: can't access dead object
  • TypeError: can't define property "x": "obj" is not extensible
  • TypeError: can't delete non-configurable array element
  • TypeError: can't redefine non-configurable property "x"
  • TypeError: cyclic object value
  • TypeError: invalid 'in' operand "x"
  • TypeError: invalid Array.prototype.sort argument
  • TypeError: invalid arguments
  • TypeError: invalid assignment to const "x"
  • TypeError: property "x" is non-configurable and can't be deleted
  • TypeError: setting getter-only property "x"
  • TypeError: variable "x" redeclares argument
  • URIError: malformed URI sequence
  • Warning: -file- is being assigned a //# sourceMappingURL, but already has one
  • Warning: 08/09 is not a legal ECMA-262 octal constant
  • Warning: Date.prototype.toLocaleFormat is deprecated
  • Warning: JavaScript 1.6's for-each-in loops are deprecated
  • Warning: String.x is deprecated; use String.prototype.x instead
  • Warning: expression closures are deprecated
  • Warning: unreachable code after return statement
  • JavaScript technologies overview
  • Lexical grammar
  • Enumerability and ownership of properties
  • Iteration protocols
  • Transitioning to strict mode
  • Template literals
  • Deprecated features
  • ECMAScript 2015 support in Mozilla
  • ECMAScript 5 support in Mozilla
  • ECMAScript Next support in Mozilla
  • Firefox JavaScript changelog
  • New in JavaScript 1.1
  • New in JavaScript 1.2
  • New in JavaScript 1.3
  • New in JavaScript 1.4
  • New in JavaScript 1.5
  • New in JavaScript 1.6
  • New in JavaScript 1.7
  • New in JavaScript 1.8
  • New in JavaScript 1.8.1
  • New in JavaScript 1.8.5
  • Documentation:
  • All pages index
  • Methods index
  • Properties index
  • Pages tagged "JavaScript"
  • JavaScript doc status
  • The MDN project

JavaScript's Destructuring Assignment

assignment in destructuring javascript

  • Introduction

If you wanted to select elements from an array or object before the ES2015 update to JavaScript, you would have to individually select them or use a loop.

The ES2015 specification introduced the destructuring assignment , a quicker way to retrieve array elements or object properties into variables.

In this article, we'll use the destructuring assignment to get values from arrays and objects into variables. We'll then see some advanced usage of the destructuring assignment that allows us to set default values for variables, capture unassigned entries, and swap variables in one line.

  • Array Destructuring

When we want to take items from an array and use them in separate variables, we usually write code like this:

Since the major ES2015 update to JavaScript, we can now do that same task like this:

The second, shorter example used JavaScript's destructuring syntax on myArray . When we destructure an array, we are copying the values of its elements to variables. Array destructuring syntax is just like regular variable assignment syntax ( let x = y; ). The difference is that the left side consists of one or more variables in an array .

The above code created three new variables: first , second , and third . It also assigned values to those variables: first is equal to 1, second is equal to 2, and third is equal to 3.

With this syntax, JavaScript sees that first and 1 have the same index in their respective arrays, 0. The variables are assigned values corresponding to their order. As long as the location matches between the left and right side, the destructuring assignment will be done accordingly.

The destructuring syntax also works with objects, let's see how.

  • Object Destructuring

Before the destructuring syntax was available, if we wanted to store an object's properties into different variables we would write code like this:

With the destructuring syntax, we can now quickly do the same thing with fewer lines of code:

While array items are destructured via their position, object properties are destructured by their key name. In the above example, after declaring the object foobar we then create two variables: foo and bar . Each variable is assigned the value of the object property with the same name. Therefore foo is "hello" and bar is "world".

Note : The destructuring assignment works whether you declare a variable with var , let , or const .

If you prefer to give a different variable name while destructuring an object, we can make a minor adjustment to our code:

With a colon, we can match an object property and give the created variable a new name. The above code does not create a variable foo . If you try to use foo you will get a ReferenceError , indicating that it was not defined.

Now that we've got the basics of destructuring arrays and objects, let's look at some neat tricks with this new syntax. We'll start with our option to select default values.

  • Default Values in Destructured Variables

What happens if we try to destructure more variables than the number of array elements or object properties? Let's see with a quick example:

Our output will be:

Unassigned variables are set to undefined . If we want to avoid our destructured variables from being undefined , we can give them a default value . Let's reuse the previous example, and default alpha3 to 'c':

If we run this in node or the browser, we will see the following output in the console:

Default values are created by using the = operator when we create a variable. When we create variables with a default value, if there's a match in the destructuring environment it will be overwritten.

Let's confirm that's the case with the following example, which sets a default value on an object:

In the above example, we default prime1 to 1. It should be overwritten to be 2 as there is a prime1 property on the object in the right-hand side of the assignment. Running this produces:

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Great! We've confirmed that default values are overwritten when there's a match. This is also good because the first prime number is indeed 2 and not 1.

Default values are helpful when we have too little values in the array or object. Let's see how to handle cases when there are a lot more values that don't need to be variables.

  • Capturing Unassigned Entries in a Destructured Assignment

Sometimes we want to select a few entries from an array or object and capture the remaining values we did not put into individual variables. We can do just that with the ... operator.

Let's place the first element of an array into a new variable, but keep the other elements in a new array:

In the above code, we set favoriteSnack to 'chocolate'. Because we used the ... operator, fruits is equal to the remaining array items, which is ['apple', 'banana', 'mango'] .

We refer to variables created with ... in the destructuring assignment as the rest element . The rest element must be the last element of the destructuring assignment.

As you may have suspected, we can use the rest element in objects as well:

We extract the id property of the object on the right-hand side of the destructuring assignment into its own variable. We then put the remaining properties of the object into a person variable. In this case, id would be equal to 1020212 and person would be equal to { name: 'Tracy', age: 24 } .

Now that we've seen how to keep all the data, let's see how flexible the destructuring assignment is when we want to omit data.

  • Selective Values in a Destructuring Assignment

We don't have to assign every entry to a variable. For instance, if we only want to assign one variable from many options we can write:

We assigned name to 'Katrin' from the array and city to 'New York City' from the object. With objects, because we match by key names it's trivial to select particular properties we want in variables. In the above example, how could we capture 'Katrin' and 'Eva' without having to take 'Judy' as well?

The destructuring syntax allows us to put holes for values we aren't interested in. Let's use a hole to capture 'Katrin' and 'Eva' in one go:

Note the gap in the variable assignment between name1 and name2 .

So far we have seen how flexible the destructuring assignment can be, albeit only with flat values. In JavaScript, arrays can contain arrays and objects can be nested with objects. We can also have arrays with objects and objects with arrays. Let's see how the destructuring assignment handles nested values.

  • Destructuring Nested Values

We can nest destructuring variables to match nested entries of an array and object, giving us fine-grained control of what we select. Consider having an array of arrays. Let's copy the first element of each inner array into their own variable:

Running this code will display the following output:

By simply wrapping each variable in the left-hand side with [] , JavaScript knows that we want the value within an array and not the array itself.

When we destructure nested objects, we have to match the key of the nested object to retrieve it. For example, let's try to capture some details of a prisoner in JavaScript:

To get the yearsToServe property, we first need to match the nested crimes object. In this case, the right-hand side has a yearsToServe property of the crimes object set to 25. Therefore, our yearsToServe variable will be assigned a value of 25.

Note that we did not create a crimes object in the above example. We created two variables: name and yearsToServe . Even though we must match the nested structure, JavaScript does not create intermediate objects.

You've done great so far in covering a lot of the destructured syntax capabilities. Let's have a look at some practical uses for it!

  • Use Cases for Destructuring Arrays and Objects

There are many uses for destructuring arrays and object, in addition to the lines of code benefits. Here are a couple of common cases where destructuring improves the readability of our code:

Developers use the destructuring assignment to quickly pull values of interest from an item in a for loop. For example, if you wanted to print all the keys and values of an object, you can write the following:

First, we create a greetings variable that stores how to say "hello" in different languages. Then we loop through the values of the object using the Object.entries() method which creates a nested array. Each object property is represented by 2 dimensional array with the first item being the key and the second item being its value. In this case, Object.entries() creates the following array [['en', 'hi'], ['es', 'hola'], ['fr', 'bonjour']] .

In our for loop, we destructure the individual arrays into key and value variables. We then log them to the console. Executing this program gives the following output:

  • Swapping Variables

We can use the destructuring syntax to swap variables without a temporary variable. Let's say you're at work and taking a break. You wanted some tea, while your coworker wanted some coffee. Unfortunately, the drinks got mixed up. If this were in JavaScript, you can easily swap the drinks using the destructuring syntax:

Now myCup has 'tea' and coworkerCup has 'coffee'. Note how we did not have let , const , or var when using the destructuring assignment. As we aren't declaring new variables, we need to omit those keywords.

With the destructuring assignment, we can quickly extract values from arrays or objects and put them into their own variables. JavaScript does this by matching the variable's array position, or the name of the variable with the name of the object property.

We've seen that we can assign default values to variables we are creating. We can also capture the remaining properties of arrays and objects using the ... operator. We can skip entries by having holes, which are indicated by commas with nothing in between them. This syntax is also flexible enough to destructure nested arrays and objects.

We provided a couple of nifty places to use the destructuring assignment. Where will you use them next?

You might also like...

  • ES6 Iterators and Generators
  • Getting Started with Camo
  • ES6 Symbols
  • Arrow Functions in JavaScript

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

In this article

assignment in destructuring javascript

React State Management with Redux and Redux-Toolkit

Coordinating state and keeping components in sync can be tricky. If components rely on the same data but do not communicate with each other when...

David Landup

Getting Started with AWS in Node.js

Build the foundation you'll need to provision, deploy, and run Node.js applications in the AWS cloud. Learn Lambda, EC2, S3, SQS, and more!

© 2013- 2024 Stack Abuse. All rights reserved.

Popular Tutorials

Popular examples, reference materials, learn python interactively, js introduction.

  • Getting Started
  • JS Variables & Constants
  • JS console.log
  • JavaScript Data types
  • JavaScript Operators
  • JavaScript Comments
  • JS Type Conversions

JS Control Flow

  • JS Comparison Operators
  • JavaScript if else Statement
  • JavaScript for loop
  • JavaScript while loop
  • JavaScript break Statement
  • JavaScript continue Statement
  • JavaScript switch Statement

JS Functions

  • JavaScript Function
  • Variable Scope
  • JavaScript Hoisting
  • JavaScript Recursion

JavaScript Objects

  • JavaScript Methods & this
  • JavaScript Constructor
  • JavaScript Getter and Setter
  • JavaScript Prototype
  • JavaScript Array
  • JS Multidimensional Array
  • JavaScript String
  • JavaScript for...in loop
  • JavaScript Number

JavaScript Symbol

Exceptions and Modules

  • JavaScript try...catch...finally
  • JavaScript throw Statement
  • JavaScript Modules

JavaScript ES6

  • JavaScript Arrow Function
  • JavaScript Default Parameters
  • JavaScript Template Literals
  • JavaScript Spread Operator
  • JavaScript Map
  • JavaScript Set
  • Destructuring Assignment
  • JavaScript Classes
  • JavaScript Inheritance
  • JavaScript for...of
  • JavaScript Proxies

JavaScript Asynchronous

  • JavaScript setTimeout()
  • JavaScript CallBack Function
  • JavaScript Promise
  • Javascript async/await
  • JavaScript setInterval()

Miscellaneous

  • JavaScript JSON
  • JavaScript Date and Time
  • JavaScript Closure
  • JavaScript this
  • JavaScript use strict
  • Iterators and Iterables
  • JavaScript Generators
  • JavaScript Regular Expressions
  • JavaScript Browser Debugging
  • Uses of JavaScript

JavaScript Tutorials

JavaScript Constructor Function

  • JavaScript console.log()

JavaScript Destructuring Assignment

  • JavaScript Destructuring

The destructuring assignment introduced in ES6 makes it easy to assign array values and object properties to distinct variables . For example, Before ES6:

Note : The order of the name does not matter in object destructuring.

For example, you could write the above program as:

Note : When destructuring objects, you should use the same name for the variable as the corresponding object key.

For example,

If you want to assign different variable names for the object key, you can use:

  • Array Destructuring

You can also perform array destructuring in a similar way. For example,

  • Assign Default Values

You can assign the default values for variables while using destructuring. For example,

In the above program, arrValue has only one element. Hence,

  • the x variable will be 10
  • the y variable takes the default value 7

In object destructuring, you can pass default values in a similar way. For example,

  • Swapping Variables

In this example, two variables are swapped using the destructuring assignment syntax.

You can skip unwanted items in an array without assigning them to local variables. For example,

In the above program, the second element is omitted by using the comma separator , .

Assign Remaining Elements to a Single Variable

You can assign the remaining elements of an array to a variable using the spread syntax ... . For example,

Here, one is assigned to the x variable. And the rest of the array elements are assigned to y variable.

You can also assign the rest of the object properties to a single variable. For example,

Note : The variable with the spread syntax cannot have a trailing comma , . You should use this rest element (variable with spread syntax) as the last variable.

  • Nested Destructuring Assignment

You can perform nested destructuring for array elements. For example,

Here, the variable y and z are assigned nested elements two and three .

In order to execute the nested destructuring assignment, you have to enclose the variables in an array structure (by enclosing inside [] ).

You can also perform nested destructuring for object properties. For example,

In order to execute the nested destructuring assignment for objects, you have to enclose the variables in an object structure (by enclosing inside {} ).

Note : Destructuring assignment feature was introduced in ES6 . Some browsers may not support the use of the destructuring assignment. Visit Javascript Destructuring support to learn more.

Table of Contents

  • Skipping Items
  • Arbitrary Number of Elements

Sorry about that.

Related Tutorials

JavaScript Tutorial

Home » JavaScript Tutorial » JavaScript Object Destructuring

JavaScript Object Destructuring

Summary : in this tutorial, you’ll learn about JavaScript object destructuring which assigns properties of an object to individual variables.

If you want to learn how to destructure an array , you can check out the array destructuring tutorial .

Introduction to the JavaScript object destructuring assignment

Suppose you have a person object with two properties: firstName and lastName .

Before ES6, when you want to assign properties of the person object to variables, you typically do it like this:

ES6 introduces the object destructuring syntax that provides an alternative way to assign properties of an object to variables:

In this example, the firstName and lastName properties are assigned to the fName and lName variables respectively.

In this syntax:

The identifier before the colon ( : ) is the property of the object and the identifier after the colon is the variable.

Notice that the property name is always on the left whether it’s an object literal or object destructuring syntax.

If the variables have the same names as the properties of the object, you can make the code more concise as follows:

In this example, we declared two variables firstName and lastName , and assigned the properties of the person object to the variables in the same statement.

It’s possible to separate the declaration and assignment. However, you must surround the variables in parentheses:

If you don’t use the parentheses, the JavaScript engine will interpret the left-hand side as a block and throw a syntax error.

When you assign a property that does not exist to a variable using the object destructuring, the variable is set to undefined . For example:

In this example, the middleName property doesn’t exist in the person object, therefore, the middleName variable is undefined .

Setting default values

You can assign a default value to the variable when the property of an object doesn’t exist. For example:

In this example, we assign an empty string to the middleName variable when the person object doesn’t have the middleName property.

Also, we assign the currentAge property to the age variable with the default value of 18.

However, when the person object does have the middleName property, the assignment works as usual:

Destructuring a null object

A function may return an object or null in some situations. For example:

And you use the object destructuring assignment:

The code will throw a TypeError :

To avoid this, you can use the OR operator ( || ) to fallback the null object to an empty object:

Now, no error will occur. And the firstName and lastName will be undefined .

Nested object destructuring

Assuming that you have an employee object which has a name object as the property:

The following statement destructures the properties of the nested name object into individual variables:

It’s possible to do multiple assignment of a property to multiple variables:

Destructuring function arguments

Suppose you have a function that displays the person object:

It’s possible to destructure the object argument passed into the function like this:

It looks less verbose especially when you use many properties of the argument object. This technique is often used in React.

  • Object destructuring assigns the properties of an object to variables with the same names by default.

Craig Buckler

Destructuring Objects and Arrays in JavaScript

Share this article

ES6 Destructuring Assignment

How to use the Destructuring Assignment

Destructuring use cases, further reading, frequently asked questions (faqs) about es6 destructuring assignment.

In JavaScript, the destructuring assignment allows you to extract individual items from arrays or objects and place them into variables using a shorthand syntax. When working with complex data, destructuring can simplify your code by allowing you to easily extract only the values that you need, assign default values, ignore values, and use the rest property to handle the leftover elements or properties. It is often used in scenarios such as working with APIs responses, functional programming, and in React and other frameworks and libraries. By simple example, destructuring can make your code look cleaner and easier to read:

Destructuring Arrays

Destructuring objects, destructuring nested objects.

  • the left-hand side of the assignment is the destructuring target — the pattern which defines the variables being assigned
  • the right-hand side of the assignment is the destructuring source — the array or object which holds the data being extracted.

Easier Declaration

Variable value swapping, default function parameters, returning multiple values from a function, for-of iteration, regular expression handling.

  • Destructuring Assignment – MDN
  • Is there a performance hit for using JavaScript Destructuring – Reddit
  • the for...of Statement – MDN

What is the basic syntax of ES6 destructuring assignment?

The basic syntax of ES6 destructuring assignment involves declaring a variable and assigning it a value from an object or array. For instance, if you have an object person with properties name and age , you can extract these values into variables using the following syntax: let {name, age} = person; . This will create two new variables name and age with the values from the corresponding properties in the person object.

Can I use ES6 destructuring assignment with arrays?

Yes, ES6 destructuring assignment can be used with arrays. The syntax is similar to object destructuring, but uses square brackets instead of curly braces. For example, if you have an array let arr = [1, 2, 3]; , you can extract these values into variables using the following syntax: let [a, b, c] = arr; . This will create three new variables a , b , and c with the values from the corresponding indices in the array.

How can I use default values with ES6 destructuring assignment?

ES6 destructuring assignment allows you to specify default values for variables that are not found in the object or array. This is done by appending = defaultValue after the variable name. For example, let {name = 'John', age = 30} = person; will assign the default values ‘John’ and 30 to name and age respectively if these properties do not exist in the person object.

Can I use ES6 destructuring assignment to swap variables?

Yes, one of the powerful features of ES6 destructuring assignment is the ability to swap variables without the need for a temporary variable. For example, if you have two variables a and b , you can swap their values using the following syntax: [a, b] = [b, a]; .

How can I use ES6 destructuring assignment with function parameters?

ES6 destructuring assignment can be used with function parameters to extract values from objects or arrays passed as arguments. For example, if you have a function that takes an object as a parameter, you can extract the object properties into variables using the following syntax: function greet({name, age}) { console.log( Hello, my name is ${name} and I am ${age} years old. ); } .

Can I use ES6 destructuring assignment with nested objects or arrays?

Yes, ES6 destructuring assignment can be used with nested objects or arrays. The syntax involves specifying the path to the nested property or index. For example, if you have a nested object let person = {name: 'John', address: {city: 'New York', country: 'USA'}}; , you can extract the nested properties into variables using the following syntax: let {name, address: {city, country}} = person; .

What is the purpose of using ES6 destructuring assignment?

ES6 destructuring assignment is a convenient way of extracting multiple properties from objects or elements from arrays into distinct variables. This can make your code cleaner and more readable, especially when dealing with complex data structures.

Can I use ES6 destructuring assignment with rest parameters?

Yes, ES6 destructuring assignment can be used with rest parameters to collect the remaining elements of an array into a new array. The syntax involves appending ... before the variable name. For example, let [a, b, ...rest] = [1, 2, 3, 4, 5]; will assign the first two elements to a and b , and the remaining elements to the rest array.

Can I use ES6 destructuring assignment to extract properties from objects into new variables with different names?

Yes, ES6 destructuring assignment allows you to extract properties from objects into new variables with different names. This is done by specifying the new variable name after a colon. For example, let {name: firstName, age: years} = person; will create two new variables firstName and years with the values from the name and age properties respectively.

What happens if I try to destructure a property or element that does not exist?

If you try to destructure a property from an object or an element from an array that does not exist, the variable will be assigned the value undefined . However, you can specify a default value to be used in such cases, as explained in Question 3.

Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler .

SitePoint Premium

  • DSA with JS - Self Paced
  • JS Tutorial
  • JS Exercise
  • JS Interview Questions
  • JS Operator
  • JS Projects
  • JS Examples
  • JS Free JS Course
  • JS A to Z Guide
  • JS Formatter

What is a Destructuring assignment and explain it in brief in JavaScript ?

  • Destructuring Assignment in JavaScript
  • Bitwise AND Assignment (&=) Operator in JavaScript
  • How to swap variables using destructuring assignment in JavaScript ?
  • What is a Function in JavaScript ?
  • Division Assignment(/=) Operator in JavaScript
  • What is the (function() { } )() construct in JavaScript?
  • What is an Array in JavaScript ?
  • What is Parameter Destructuring in TypeScript ?
  • Nullish Coalescing Assignment (??=) Operator in JavaScript
  • Destructive vs Non-Destructive Approach in JavaScript Arrays
  • Explain the Different Function States in JavaScript
  • Explain the difference between undefined and not defined in JavaScript
  • How to set default values when destructuring an object in JavaScript ?
  • What is shallow copy and deep copy in JavaScript ?
  • What happen when we directly assign the variable without declaring it in JavaScript ?
  • How Inheritance works in Constructor Functions in JavaScript ?
  • What is the difference between Map and WeakMap in JavaScript ?
  • What are the __construct() and __destruct() methods in a PHP ?
  • What is Object.defineProperty() in JavaScript?
  • Explain Scope and Scope Chain in JavaScript
  • What are Closures in JavaScript ?
  • What is function scope in JavaScript?
  • Implement Custom Function to Deep clone in JavaScript
  • What happens inside JavaScript Engine ?
  • Explore the concept of JavaScript Function Scope and different types of JavaScript Functions
  • How to create a function that invokes function with partials prepended arguments in JavaScript ?
  • What are Pure Functions in JavaScript ?
  • Is it possible to call constructor and destructor explicitly in C++?
  • Exception Handling and Object Destruction in C++

The Destructuring assignment is the important technique introduced in ECMAScript 2015 (ES6) version of JavaScript that provides a shorthand syntax to extract or unpack array elements or properties of an object into distinct variables using a single line of code. In other words, this assignment helps us to segregate data of any iterable as well as non-iterable object and then helps us to use that segregated data individually on need or demand. It makes the code shorter and more readable.

Let us have a look over the below mentioned syntax of Destructuring assignment which will help us to reduce our code and make it more readable and scalable too. 

Syntax: The left-hand side of the expression of Destructuring assignment contains the distinct variables which actually defines what properties/values are to be unpacked or segregated from the source variable (or an array or an object) and the right-hand side specifies the corresponding object or array to which we are about to extract our data (the source variable which could be any iterable or non-iterable object). 

Example 1: The following example showcases the usage of extracting required array elements into distinct variables using Array Destructuring and will also help you to understand how Destructuring can be used to write clean and concise code.

Example 2: The spread operator is also used to unpack array elements but the main difference between Array Destructuring and spread operator is that spread unpacks all the array elements and this spread operator doesn’t allow us to skip or choose elements according to our requirement. Using Array Destructuring, we can skip the elements which are not required by using a ‘comma separator.’

Example 3: In the following example, an address object is de-structured to obtain only the city and sector properties and display the output on the console. 

Object Destructuring is an important feature of JavaScript and is very useful when only certain properties of an object are to be used and the complete object is not required or  not in consideration. This feature of ES6 is commonly used in JavaScript frameworks and its main application is parameter de-structuring i.e. objects passed into function parameters can be de-structured before use, according to the function requirement.

Note: The order of name doesn’t matter in case we are implementing Object Destructuring in JavaScript.

For example, in the above illustrated example, if we change the order of names in which the particular object’s properties has been de-structured from the source object, then also our task will be same and result would also be the same. Let us see the implementation of this illustrated fact below (with the help of following code snippet):

Example 4: Object properties can also be extracted using a different variable name (an alias) other than the property name defined in the source object. The following example uses aliases to extract the values of state and city properties from the address object.

Example 5: A nested object i.e. an object within the source object can also be de-structured using the same syntax of Object Destructuring to access only the properties required. The example below contains an address object having a nested object pin which is de-structured to extract only the pin-code of the address.

Example-6: In this example we will try to understand how actually setting function parameter’s default value task works. In other words using the below mentioned code snippet we will try to understand how we may set a function parameter’s default value.

Please Login to comment...

Similar reads.

  • Geeks-Premier-League-2022
  • JavaScript-Questions
  • Geeks Premier League
  • Web Technologies

advertisewithusBannerImg

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

JavaScript Destructuring and the Spread Operator – Explained with Example Code

Nishant Kumar

JavaScript has two awesome data structures that help you write clean and efficient code. But handling them can get messy sometimes.

In this blog, I am going to show you how to handle destructuring in arrays and objects in JavaScript. We'll also learn how to use the spread operator as well.

Let's dive in.

What is Array Destructuring in JavaScript?

Let's say we have an array that contains five numbers, like this:

To get the elements from the array, we can do something like getting the number according to its indexes:

But this method is old and clunky, and there is a better way to do it – using array destructuring. It looks like this:

Both methods above will yield the same result:

Screenshot-2021-08-07-105209

Now, we have five elements in the array, and we print those.  But what if we want to skip one element in between?

Here, we have skipped indexThird , and there's an empty space between indexTwo and indexFour.

Screenshot-2021-08-07-105709

You can see that we are not getting the third element because we have set it as empty.

What is Object Destructuring in JavaScript?

This destructuring works well with objects too. Let me give you an example.

Let's say we want the name, salary, and weight from this object to be printed out in the console.

We can get them using the keys, which are name, salary, and weight.

But this code becomes difficult to understand sometimes. That's when destructuring comes in handy:

And now, we can just log name, salary, and weight instead of using that old method.

Screenshot-2021-08-07-111356

We can also use destructuring to set default values if the value is not present in the object.

Here, we have name and weight present in the object, but not the salary:

Screenshot-2021-08-07-111659

We will get an undefined value for the salary.

To correct that issue, we can set default values when we are destructuring the object.

Screenshot-2021-08-07-111907

You can see that we get 200 as the Salary. This only works when we don't have that key in the object, and we want to set a default value.

Add salary in the object, and you will get 300 as the salary.

Screenshot-2021-08-07-112128

How to Use Object Destructuring with Functions

Let's say we have a function that prints all the data in the array to the console.

We are passing the object as a parameter in the function when it gets called:

Normally, we would do something like this – passing the object and logging it in the console.

Screenshot-2021-08-07-115047

But again, we can do the same using destructuring.

Here, we are destructuring the object into name, age, salary, height and weight in the function parameters and we print everything on the same line.

You can see how destructuring makes it so much easier to understand.

Screenshot-2021-08-07-115329

Let's look at one last example.

We have a function here which accepts two numbers. It returns an array adding them and multiplying them and logs them into the console.

Screenshot-2021-08-07-120108

Let's use destructuring here instead.

We can destructure it into addition and multiplication variables like this:

Screenshot-2021-08-07-120325

And in the output, you can see we get the addition and multiplication of both numbers.

What is the Spread Operator in JavaScript?

Spread means spreading or expanding. And the spread operator in JavaScript is denoted by three dots.

This spread operator has many different uses. Let's see them one by one.

Spread Operator Examples

Let's say we have two arrays and we want to merge them.

Screenshot-2021-08-07-112601

We are getting the combination of both arrays, which are array1 and array2.

But there is an easier way to do this:

In this case, we are using the spread operator to merge both arrays.

Screenshot-2021-08-07-113020

And you can see, we will get the same output.

Let's imagine another use case where we have to insert array1 between the elements of array2 .

For example, we want to insert array2 between the second and third element of array1 .

So, how do we do that? We can do something like this:

Screenshot-2021-08-07-113502

And you can see, we get the array1 elements between 7 and 8.

Now, let's merge two objects together using the spread operator.

We have two objects here. One contains firstName, age, and salary. The second one contains lastName, height, and weight.

Let's merge them together.

We have now merged both objects using the spread operator, and we've logged the value in the console.

Screenshot-2021-08-07-114101

You can see that we are getting the combination of both objects.

Lastly, we can also copy one array into another using the spread operator. Let me show you how it works:

Here, we are copying array1 into array2 using the spread operator.

Screenshot-2021-08-07-120757

We are logging array2 in the console, and we are getting the items of array1 .

That's all, folks! In this article, we learned about array and object destructuring and the spread operator.

You can also watch my Youtube video on Array and Object Destructuring and the Spread Operator if you want to supplement your learning.

Happy Learning.

I build projects to learn how code works. And while I am not coding, I enjoy writing poetry and stories, playing the piano, and cooking delicious meals.

If you read this far, thank the author to show them you care. Say Thanks

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started

React Tutorial

React hooks, react exercises, react es6 destructuring, destructuring.

To illustrate destructuring, we'll make a sandwich. Do you take everything out of the refrigerator to make your sandwich? No, you only take out the items you would like to use on your sandwich.

Destructuring is exactly the same. We may have an array or object that we are working with, but we only need some of the items contained in these.

Destructuring makes it easy to extract only what is needed.

Destructing Arrays

Here is the old way of assigning array items to a variable:

Here is the new way of assigning array items to a variable:

With destructuring:

When destructuring arrays, the order that variables are declared is important.

If we only want the car and suv we can simply leave out the truck but keep the comma:

Destructuring comes in handy when a function returns an array:

Try it Yourself »

Get Certified!

Destructuring objects.

Here is the old way of using an object inside a function:

Here is the new way of using an object inside a function:

Notice that the object properties do not have to be declared in a specific order.

We can even destructure deeply nested objects by referencing the nested object then using a colon and curly braces to again destructure the items needed from the nested object:

Test Yourself With Exercises

Use destructuring to extract only the third item from the array, into a variable named suv .

Start the Exercise

Get Certified

COLOR PICKER

colorpicker

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: [email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail: [email protected]

Top Tutorials

Top references, top examples, get certified.

Featured Topics

assignment in destructuring javascript

Design systems

assignment in destructuring javascript

Engineering

Explore topics.

  • Accessibility
  • Behind the scenes
  • Brainstorming
  • Career & education
  • Collaboration
  • Design thinking
  • Diagramming
  • Infrastructure
  • Localization
  • Plugins & tooling
  • Product management
  • Product updates
  • Productivity
  • Profiles & interviews
  • Prototyping
  • Quality & performance
  • Social impact
  • The Long & Short of It
  • Thought leadership
  • Tips & inspiration
  • Wireframing

Figma’s journey to TypeScript: Compiling away our custom programming language

assignment in destructuring javascript

We’ve long written core parts of our mobile rendering architecture in Skew, the custom programming language we invented to squeeze additional performance out of our playback engine. Here’s how we automatically migrated Skew to TypeScript without disrupting a single day of development.

Skew began as a side project in the early days of Figma. At the time, Skew fulfilled a critical need at Figma: to build out our prototype viewer with support on both the web and mobile. What started as a way to quickly spin this up became an entire compile-to-JavaScript programming language that enabled more advanced optimizations and faster compile times. But as we accumulated more and more code in Skew in the prototype viewer over the years, we slowly realized that it was difficult for new hires to ramp up on, couldn’t easily integrate with the rest of our codebase, and was missing a developer ecosystem outside of Figma. The pain of scaling it grew to outweigh its original advantages.

We recently finished migrating all Skew code at Figma to TypeScript, the industry standard language for the web. TypeScript is a sea change for the team and enables:

  • Streamlined integration with both internal and external code via static imports and native package management
  • A massive developer community that has built tools like linters, bundlers, and static analyzers
  • Modern JavaScript features like async/await and a more flexible type system
  • Seamless onboarding for new developers and lower friction for other teams

A snippet of Skew code

This migration only recently became possible for three reasons:

  • More mobile browsers started to support WebAssembly
  • We replaced many core components of our Skew engine with the corresponding components from our C++ engine, which meant we wouldn’t lose as much performance if we moved to TypeScript
  • Team growth allowed us to allocate resources to focus on the developer experience

WebAssembly saw widespread mobile support and improved performance

When we first built Figma’s mobile codebase, mobile browsers didn’t support WebAssembly and couldn’t load large bundles in a performant way. This meant that it wasn’t possible to use our main C++ engine code (which would need to compile to WebAssembly). At the same time, TypeScript was in its infancy; it wasn’t the obvious choice compared to Skew, which had static types and a stricter type system that allowed for advanced compiler optimizations . Fortunately, WebAssembly obtained widespread mobile support by 2018 and, according to our tests, reliable mobile performance by 2020.

Other performance improvements caught up to Skew’s optimizations

When we first started using Skew, there were a few key benefits: classic compiler optimizations, like constant folding and devirtualization, along with web-specific ones like generating JavaScript code with real integer operations. The longer we spent with these optimizations, the harder it was to justify a departure from a language we had cultivated for so long. For instance, in 2020, benchmarks indicated that loading Figma prototypes would’ve been nearly twice as slow using TypeScript in Safari, which was a blocker because Safari was (and still is*) the only browser engine allowed on iOS.

*In iOS 17.4, Apple opened up its system to other browser engines for users in the EU . WebKit remains the only browser engine for other users around the world.

Some years after WebAssembly obtained widespread mobile support, we replaced many core components of our Skew engine with the corresponding components from our C++ engine. Since the components we replaced were the hottest code paths—like file loading—we wouldn’t lose as much performance if we moved to TypeScript. This experience gave us confidence that we could forego the advantages of Skew’s optimizing compiler.

Figma’s prototyping and mobile teams grew

In Figma’s earlier years, we couldn’t justify diverting resources to perform an automated migration because we were building as fast as possible with a small team. Scaling the prototyping and mobile teams into larger organizations afforded us the resources to do so.

Converting the codebase

When we first prototyped this migration in 2020, our benchmarks showed that performance would be nearly twice as slow using TypeScript. Once we saw that WebAssembly support was good enough and moved the core of the mobile engine to C++, we fixed up our old prototype during our company Maker Week . We demonstrated a working migration that passed all tests. Despite the thousands of developer experience issues and non-fatal type errors, we had a rough plan to migrate all of our Skew code safely.

Our goal was simple: convert the whole codebase to TypeScript. While we could have manually rewritten each file, we couldn’t afford to interrupt developer velocity to rewrite the entire codebase. More importantly, we wanted to avoid runtime errors and performance degradations for our users. While we ended up automating this migration, it wasn’t a quick switch. Unlike moving from another “JavaScript-with-types” language to TypeScript, Skew had actual semantic differences that made us uncomfortable with an immediate switch to TypeScript. For example, TypeScript only initializes namespaces and classes after we import a file, meaning we could run into runtime errors if we import the files in an unexpected order. By contrast, Skew makes every symbol available at runtime to the rest of the codebase upon loading, so these runtime errors wouldn’t be a problem.

Evan has said he took some learnings from this experience to make web bundler esbuild .

We opted to gradually roll out a new code bundle generated from TypeScript so that there would be minimal disruptions to developer workflows. We developed a Skew-to-TypeScript transpiler that could take Skew code as input and output generated TypeScript code, building upon the work that Evan Wallace, Figma’s former CTO, started years ago.

Phase 1: Write Skew, build Skew

We kept the original build process intact, developed the transpiler, and checked in the TypeScript code to GitHub to show developers what the new codebase would look like.

Developing a Typescript transpiler, alongside our original Skew pipeline

Phase 2: Write Skew, build TypeScript

Once we generated a TypeScript bundle that passed all of our unit tests, we started rolling out production traffic to build from the TypeScript codebase directly. In this phase, developers still wrote Skew, and our transpiler transpiled their code into TypeScript and updated TypeScript code living in GitHub. Additionally, we continued to fix type errors in the generated code; TypeScript could still generate a valid bundle even if there were type errors!

Rolling out production traffic to the TypeScript codebase that our TypeScript compiler generated from Skew source code

Phase 3: Write TypeScript, build TypeScript

Once everyone went through the TypeScript build process, we needed to make the TypeScript code the source of truth for development. After identifying a time when no one was merging code, we cut off the auto-generation process and deleted the Skew code from the codebase, effectively requiring that developers write code in TypeScript.

Making the cutover to use the Typescript codebase as the source of truth for developers

This was a solid approach. Having full control over the workings of the Skew compiler meant we could use it to make Phase 1 much easier; we could add and modify parts of the Skew compiler with complete freedom to satisfy our needs. Our gradual rollout also ended up paying dividends. For example, we internally caught a breakage with our Smart Animate feature as we were rolling out TypeScript. Our gated approach allowed us to quickly turn off the rollout, fix the breakage, and rethink how to proceed with our rollout plan.

We also gave ample notice about the cutover to use TypeScript. On a Friday night, we merged all the necessary changes to remove the auto-generation process and to make all of our continuous integration jobs run off the TypeScript files directly.

A note on our transpiler work

If you don’t know how compilers work, here’s a bird’s-eye view: A compiler itself consists of a frontend and a backend. The frontend is responsible for parsing and understanding the input code and performing things like type-checking and syntax checking. The frontend then converts this code to an intermediate representation (IR), a data structure that fully captures the original semantics and logic of the original input code, but structured so that we don’t need to worry about re-parsing the code.

The backend of the compiler is responsible for turning this IR into a variety of different languages. In a language like C, for example, one backend would typically generate assembly/machine code, and in the Skew compiler, the backend generates mangled and minified JavaScript.

A transpiler is a special type of compiler whose backends produce human-readable code rather than mangled machine-like code; in our case, the backend would need to take the Skew IR and produce human-readable TypeScript.

The process of writing the transpiler was relatively straightforward in the beginning: We borrowed a lot of inspiration from the JavaScript backend with the appropriate code to generate based on the information we encountered in the IR. At the tail end we ran into several issues that were trickier to track down and deal with:

  • Performance issues with array destructuring: Moving away from JavaScript array destructuring yielded up to 25% in performance benefits.
  • Skew’s “devirtualization” optimization: We took extra steps during the rollout to make sure devirtualization, a compiler optimization, did not break our codebase’s behavior.
  • Initialization order matters in TypeScript: Symbol ordering in TypeScript matters as opposed to Skew, so our transpiler needed to generate code that respected this ordering.

Performance issues with array destructuring

When investigating offline performance differences between Skew and TypeScript in some sample prototypes, we noticed that the frame rate was lower in TypeScript. After much investigation, we found out the root cause was array destructuring–which, it turns out, is rather slow in JavaScript.

To complete an operation like const [a, b] = function_that_returns_an_array() , JavaScript constructs an iterator that iterates through the array instead of directly indexing from the array, which is slower. We were doing this to retrieve arguments from JavaScript’s arguments keyword, resulting in slower performance on certain test cases. The solution was simple: We generated code to directly index the arguments array instead of destructuring, and improved per-frame latency by up to 25%!

Skew’s “devirtualization” optimization

Check out this post to learn more about devirtualization.

Another issue was divergent behavior between how TypeScript and Skew deal with class methods, which caused the aforementioned breakage in Smart Animate during our rollout. The Skew compiler does something called devirtualization , which is when–under certain conditions–a function gets pulled out of a class as a performance optimization and gets hoisted to a global function:

This optimization happens in Skew but not TypeScript. The Smart Animate breakage happened because myObject was null, and we saw different behaviors–the devirtualized call would run fine but the non-devirtualized call would result in null access exception. This made us worry if there were other such call sites that had the same problem.

To assuage our worries, we added logging in all functions that would partake in devirtualization to see if this problem had ever occurred in production. After enabling this logging for a brief period of time, we analyzed our logs and fixed all problematic call sites, making us more confident in the robustness of our TypeScript code.

Initialization order matters in TypeScript

A third issue we encountered is how each respective language honors initialization order. In Skew, you can declare variables, classes and namespaces, and function definitions anywhere in code and it won’t care about the order in which they are declared. In TypeScript, however, it does matter whether you initialize global variables or class definitions first; initializing static class variables before the class definition is a compile-time error.

Our initial version of the transpiler got around this by generating TypeScript code without using namespaces, effectively flattening every single function into the global scope. This maintained similar behavior to Skew, but the resulting code was not very readable. We reworked parts of the transpiler to emit TypeScript code in the proper order for clarity and accuracy, and added back TypeScript namespaces for readability.

Despite these challenges, we eventually built a transpiler that passed all of our unit tests and produced compiling TypeScript code that matched Skew’s performance. We opted to fix some small issues either manually in Skew source code, or once we cut over to TypeScript—rather than writing a new modification to the transpiler to fix them. While it would be ideal for all fixes to live in the transpiler, the reality is that some changes weren’t worth automating and we could move faster by fixing some issues this way.

Case study: Keeping developers happy with source maps

Throughout this process, developer productivity was always top of mind. We wanted to make the migration to TypeScript as easy as possible, which meant doing everything we could to avoid downtime and create a seamless debugging experience.

Web developers primarily debug with debuggers supplied by modern web browsers; you set a breakpoint in your source code and when the code reaches this point, the browser will pause and developers can inspect the state of the browser’s JavaScript engine. In our case, a developer would want to set breakpoints in Skew or TypeScript (depending on which phase of the project we were in).

But the browser itself can only understand JavaScript, while breakpoints are actually set in Skew or TypeScript. How does it know where to stop in the compiled JavaScript bundle given a breakpoint in source code? Enter: source maps, the way a browser knows how to link together compiled code to source code. Let’s look at a simple example with this Skew code:

This code might get compiled and minified down to the following JavaScript:

This syntax is hard to read. Source maps map sections of the generated JavaScript back to specific sections of the source code (in our case, Skew). A source map between the code snippets would show mappings between:

  • arrayOfInts → b

Check out this article on source maps for more technical details on generating, understanding, and debugging source maps.

A source map normally will have file extension .map . One source map file will associate with the final JavaScript bundle so that, given a code location in the JavaScript file, the source map for our JavaScript bundle would tell us:

  • The Skew file this section of JavaScript came from
  • The code location within this Skew file that corresponds to this portion of JavaScript

Whenever a developer sets a debugger breakpoint in Skew, the browser simply reverses this source map, looks up the portion of JavaScript that this Skew line corresponds to, and sets a breakpoint there.

Here’s how we applied this to our TypeScript migration: Our original infrastructure generated Skew to JavaScript source maps that we used for debugging. However, in Phase 2 of our migration, our bundle generation pipeline was completely different, generating TypeScript followed by bundling with esbuild. If we tried to use the same source maps from our original infrastructure, we would get incorrect mappings between JavaScript and Skew code, and developers would be unable to debug their code while we’re in this phase.

We needed to generate new source maps using our new build process. This involved three pieces of work, illustrated below:

Diagram of generating new sourcemaps using our new build process

Step 1 : Generate a TypeScript → JavaScript source map ts-to-js.map . esbuild can automatically generate this map when it generates the JavaScript bundle.

Step 2 : Generate a Skew → TypeScript source map for each Skew source file. If we name the file file.sk , the transpiler will name the source map file.map . By emulating how the Skew → JavaScript backend of the Skew compiler creates source maps, we implemented this in our TypeScript transpiler.

Step 3 : Compose these source maps together to yield a map from Skew to JavaScript. For this, we implemented the following logic in our build process:

For each entry E in ts-to-js.map :

  • Determine which TypeScript file this entry maps into and open its source map, fileX.map .
  • Look up the TypeScript code location from E in this source map, fileX.map , to obtain the code location in the corresponding Skew file fileX.sk .
  • Add this as a new entry in our final source map: the JavaScript code location from E combined with the Skew code location.

With our final source map handy, we could now map our new JavaScript bundle to Skew without disrupting the developer experience.

Case study: Conditional compilation

In Skew, top-level “if” statements allow for conditional code compilation, and we specify the conditions using compile-time constants via a “defines” option passed to the Skew compiler. We can use this to define multiple build targets—which bundle in different parts of the code—for a given codebase, so we can have different bundles for different ways of using the same codebase. For example, one bundle variant could be the actual bundle that’s deployed to users, and another could be one used only for unit testing. This allows us to specify that certain functions or classes use different implementations in debug or release builds.

To be more explicit, the following Skew code defines a different implementation for a TEST build:

This would compile to the following JavaScript when passing a BUILD: "TEST" definition to the Skew compiler:

However, conditional compilation is not part of TypeScript. Instead, we had to perform the conditional compilation in the build step after type-checking, as part of the bundling step using esbuild’s “defines” and dead code elimination features. The defines could therefore no longer influence type-checking, meaning code like the above example where the method testOnlyFunction is only defined in the BUILD: "TEST" build could not exist in Typescript.

We fixed this problem by converting the above Skew code to the following TypeScript code:

This compiles to the same JavaScript code that the original Skew code also directly compiled to:

Unfortunately, our final bundle was now slightly larger. Some symbols that were originally only available in one compile-time mode became present in all modes. For example, we only used testOnlyFunction when the build mode BUILD was set to "TEST" , but after this change the function was always present in the final bundle. In our testing, we found this increase in bundle size to be acceptable. We were still be able to remove unexported top-level symbols, though, via tree-shaking .

A new era of prototyping development, now in TypeScript

By migrating all Skew code to TypeScript, we modernized a key codebase at Figma. Not only did we pave the way for it to integrate much more easily with internal and external code, developers are working more efficiently as a result. Writing the codebase initially in Skew was a good decision given the needs and capabilities of Figma at the time. However, technologies are constantly improving and we learned to never doubt the rate at which they mature. Even though TypeScript may not have been the right choice back then, it definitely is now.

We want to reap all the benefits of moving to TypeScript, so our work doesn’t stop here. We’re exploring a number of future possibilities: integration with the rest of our codebase, significantly easier package management, and direct use of new features from the active TypeScript ecosystem. We learned a lot about different facets of TypeScript—like import resolutions, module systems, and JavaScript code generation—and we can’t wait to put those learnings to good use.

We would like to thank Andrew Chan, Ben Drebing, and Eddie Shiang for their contributions to this project. If work like this appeals to you, come work with us at Figma !

Subscribe to Figma’s editorial newsletter

By clicking “Submit” you agree to our TOS and Privacy Policy .

Create and collaborate with Figma

IMAGES

  1. Javascript Destructuring Assignment: (Extract variables from arrays and objects in JavaScript)

    assignment in destructuring javascript

  2. JavaScript Syntaxes : Destructuring Assignment, Spread and Rest

    assignment in destructuring javascript

  3. How to Use Object Destructuring in JavaScript

    assignment in destructuring javascript

  4. JavaScript ES6:Destructuring for Beginners

    assignment in destructuring javascript

  5. How to Use Object Destructuring in JavaScript

    assignment in destructuring javascript

  6. สอน Javascript ES6

    assignment in destructuring javascript

VIDEO

  1. Practical examples of destructuring of arrays in JavaScript

  2. Destructuring Assignment in JS #coding #javascript #javascripttutorial #shorts #short #shortvideo

  3. 13 Destructuring via rest elements

  4. how to destructure an array in less than 10 seconds #javascript #coding #tutorial #shorts

  5. Learn ES6 (11/31)

  6. JavaScript Array Destructuring Part 2 [شرح جافا سكريبت]

COMMENTS

  1. Destructuring assignment

    The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables. ... The destructuring assignment uses similar syntax but uses it on the left-hand side of the assignment instead. It defines which values to unpack from the sourced variable.

  2. Destructuring assignment

    It's called "destructuring assignment," because it "destructurizes" by copying items into variables. However, the array itself is not modified. It's just a shorter way to write: // let [firstName, surname] = arr; let firstName = arr [0]; let surname = arr [1]; Ignore elements using commas.

  3. ES6 Destructuring Assignment Explained By Examples

    If not, assign the value 0 to the thirdItem variable. It'll be simpler with the destructuring assignment with a default value: let [, , thirdItem = 0] = getItems(); console.log(thirdItem); // 0 Code language: JavaScript (javascript) If the value taken from the array is undefined, you can assign the variable a default value, like this:

  4. Destructuring Assignment in JavaScript

    Array destructuring: Using the Destructuring Assignment in JavaScript array possible situations, all the examples are listed below: Example 1: When using destructuring assignment the same extraction can be done using below implementations. Example 2: The array elements can be skipped as well using a comma separator.

  5. How Destructuring Works in JavaScript

    Destructuring is a powerful JavaScript feature introduced in ES6 (ECMAScript 2015). It makes it easier to extract values from arrays or properties from objects and assign them to variables in a readable way. Let's delve into how destructuring works and explore various use cases with examples. You can get the source code from here. Table of Contents

  6. javascript

    3. It is something like what you have can be extracted with the same variable name. The destructuring assignment is a JavaScript expression that makes it possible to unpack values from arrays or properties from objects into distinct variables. Let's get the month values from an array using destructuring assignment.

  7. JavaScript Destructuring Assignment

    Destructuring assignment in JavaScript is a powerful feature that simplifies how you extract values from arrays or properties from objects. It allows you to unpack values into distinct variables concisely and readably. In this tutorial, you'll learn the basics of destructuring assignments, including working with arrays and objects and applying ...

  8. Destructuring assignment

    The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables. ... around the assignment statement is required syntax when using object literal destructuring assignment without a declaration.

  9. JavaScript's Destructuring Assignment

    Developers use the destructuring assignment to quickly pull values of interest from an item in a for loop. For example, if you wanted to print all the keys and values of an object, you can write the following: for ( const [key, value] of Object .entries(greetings)) {. console .log( `${key}: ${value}` );

  10. JavaScript Destructuring Assignment

    JavaScript Destructuring. The destructuring assignment introduced in ES6 makes it easy to assign array values and object properties to distinct variables. For example, Before ES6: // assigning object attributes to variables const person = {. name: 'Sara', age: 25, gender: 'female'. }

  11. How To Use Destructuring Assignment In JavaScript

    When destructuring objects, we use the keys as variable names. This is how JavaScript knows which property of the object you want to assign. Unlike arrays where you use their index/positions in the assignment, here you use the keys. This destructuring works on any kind of object.

  12. JavaScript Object Destructuring

    Introduction to the JavaScript object destructuring assignment. Suppose you have a person object with two properties: firstName and lastName. let person = {. firstName: 'John' , lastName: 'Doe'. }; Code language: JavaScript (javascript) Before ES6, when you want to assign properties of the person object to variables, you typically do it like this:

  13. How to Use Array and Object Destructuring in JavaScript

    The destructuring assignment is a cool feature that came along with ES6. Destructuring is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables. That is, we can extract data from arrays and objects and assign them to variables. Why

  14. Destructuring Objects and Arrays in JavaScript

    Yes, ES6 destructuring assignment can be used with arrays. The syntax is similar to object destructuring, but uses square brackets instead of curly braces. For example, if you have an array let ...

  15. Destructuring in JavaScript

    How to Swap Variables with Destructuring. Now that you know how to assign variables with destructuring, let's look at how you can use destructuring to quickly swap variable values. Say we have an array of two elements, "food" and "fruits", and we use destructuring to assign those values to the variables positionOne and positionTwo:

  16. Using the Destructuring Assignment Syntax in JavaScript

    Object Destructuring. We can use the destructuring assignment syntax for objects as well. For example, we can write: const {a,b} = {a:1, b:2}; In the code above, a is set to 1 and b is set to 2 because the key is matched to the name of the variable when assigning the values to variables.

  17. Mastering JavaScript Destructuring for Cleaner Code

    Conclusion. JavaScript destructuring is a powerful feature that offers more readable, concise, and maintainable code. By adopting this approach, developers can efficiently handle data extraction from arrays and objects, leading to cleaner and more effective code structures.

  18. What is a Destructuring assignment and explain it in brief in JavaScript

    The Destructuring assignment is the important technique introduced in ECMAScript 2015 (ES6) version of JavaScript that provides a shorthand syntax to extract or unpack array elements or properties of an object into distinct variables using a single line of code. In other words, this assignment helps us to segregate data of any iterable as well ...

  19. Destructuring assignment

    Also note that the syntax and behavior of an experimental technology is subject to change in future version of browsers as the spec changes. The destructuring assignment syntax is a JavaScript expression that makes it possible to extract data from arrays or objects using a syntax that mirrors the construction of array and object literals.

  20. Understanding Destructuring, Rest Parameters, and Spread Syntax in

    The default assignment for object destructuring creates new variables with the same name as the object property. If you do not want the new variable to have the same name as the property name, you also have the option of renaming the new variable by using a colon (:) to decide a new name, as seen with noteId in the following:// Assign a custom name to a destructured value const {id: noteId ...

  21. JavaScript Destructuring and the Spread Operator

    Let's look at one last example. function sample(a, b) {. return [a + b, a * b] } let example = sample(2, 5); console.log(example) Function to Add and Multiply two numbers. We have a function here which accepts two numbers. It returns an array adding them and multiplying them and logs them into the console.

  22. React ES6 Destructuring

    When destructuring arrays, the order that variables are declared is important. If we only want the car and suv we can simply leave out the truck but keep the comma: const vehicles = ['mustang', 'f-150', 'expedition']; const [car,, suv] = vehicles; Destructuring comes in handy when a function returns an array:

  23. Figma's journey to TypeScript

    Performance issues with array destructuring: Moving away from JavaScript array destructuring yielded up to 25% in performance benefits. Skew's "devirtualization" optimization: We took extra steps during the rollout to make sure devirtualization, a compiler optimization, did not break our codebase's behavior.