Destructuring Assignment Indepth Syntax Comparison - JavaScript Vs Python
Tags: javascript, python
Published: 2020-11-24 11:34:09

The destructuring or an unpacking assignment syntax is an expression that makes it possible to unpack values from iterables like array and objects in javascript and list, tuples, dictionaries in Python into distinct variables.This post will look at the difference in syntax used in Python and JavaScript for destructuring or unpacking assignments.

Unstructuring assignment is quite useful as it allows us to assign values to several variables at once from a single collection, is easy to understand and improves code-readability(if there exist such a term). 

One simple examples includes performing swap operation on two variables,

`Python`

```python
a = 5 
b = 7

b, a = a, b
print(a, b, sep = " ") 
# 7 5
```

`JavaScript`

```jsx
let a = 5, b = 7

[b, a] = [a, b]
console.log(a, b)
// 7 5 
```

## Array/List Destructuring

`Python`

```python
example_list = [1, 2, 3]

first, second, third = example_list
print(first, second, third, sep = " ") 

# 1 2 3
```

The above code snippet shows a simple list destructing in Python. Here the assignment of variables depends simply upon the order of items in the list.

`JavaScript`

```jsx
const example_array = [1, 2, 3]
let first, second, third
[first, second, third] = example_array

console.log(first, second, third)
// 1 2 3
```

Array Destructuring in JavaScript requires variable to be enclosed with "[ ]"

### Ignoring values

`Python`

```python
example_list = [1, 2, 3]
first, _ , third = example_list
print(first, third, sep = " ")
# 1 3
```

The values to ignored are to be replaced with ' _ '

`JavaScript`

```jsx
const example_array = [1, 2, 3]
const [first, , third] = example_array
console.log(first, third)
// 1 3
```

The values to be ignored are just empty with commas after them.

> In Python, if we try to destructure a collection with more or fewer values than we provide variables, we end up with a `ValueError`. Whereas in Javascript it will not show any error

  `Python`

```python
example_list = [1, 2, 3]
first, second = example_list
#ValueError: not enough values to unpack (expected 2)
```

`JavaScript`

```jsx
const example_array = [1, 2, 3]
let first, second, third, fourth

//when destructuring less values
[first, second] = example_array
console.log(first, second)
// 1 2

//when destructuring more values
[first, second, third, fourth] = example_array
console.log(first, second, third, fourth)
// 1 2 3 undefined
```

In JavaScript, When unpacking less number of values, only the initial values are assigned, while unpacking of more number of values, the only the first three variables are assigned a value, and the last remains as undefined.

In such a scenario, JavaScript allows us to use a default value: 

 

```jsx
[first, second, third, fourth = 4] = example_array
console.log(first, second, third, fourth)
// 1 2 3 4
```

### Collecting Values

`Python`

```python
head, *tail = [1, 2, 3, 4, 5]

print(head)  # 1
print(tail)  # [2, 3, 4, 5]
```

`JavaScript`

```jsx
const [head, ...tail] = [1, 2, 3, 4, 5]
console.log(head) // 1
console.log(tail) // [2, 3, 4, 5]
```

`...` is known as "rest" operator in JavaScript 

Be aware that a `SyntaxError` will be thrown if a trailing comma is used on the right-hand side of a rest element:

```jsx
const [a, ...b,] = [1, 2, 3];

// SyntaxError: rest element may not have a trailing comma
// Always consider using rest operator as the last element
```

## Args/Kwargs in Python and Object Destructuring in JavaScript

In Python, we can pass a variable number of arguments to a function using special symbols. There are two special symbols:

1. `*args` (Non Keyword Arguments)
2. `**kwargs` (Keyword Arguments)

A typical example where one might need something like `*args` is given below:

  

```python
// a standard function to add two numbers
def adder(x,y):
    print("sum:",x+y)
```

If we are to add multiple numbers but are unsure of how many numbers we'll have to add

We can modify adder in two ways:

* we can put the numbers to be added to a list and pass the list as an argument.

```python
def adder(nums):
	sum = 0

	for num in nums: 
		sum += num

	print("sum : ", sum)
```

But this requires to add maintain a list and remove and add numbers to list accordingly.

This is where `*args` comes into play:

Python has `*args` which allow us to pass the variable number of non keyword arguments to function.

* modifying the adder functions using *args:

```python
def adder(*num):
    sum = 0
    
    for n in num:
        sum = sum + n

    print("sum:",sum)

# args is just a conventional name used in python, we can use any name
# (like num in this example)
```

> We use *args and **kwargs as an argument when we are unsure about the number of arguments to pass in the functions.

`*args` allow to pass mulitple arguments to function while `**kwargs` allows to pass multiple keyword arguments to a function.

```python
def printSomething(a, *args, **kwargs):
	print(a)
	print(args)
	print(kwargs)

printSomething(1, 2, 3, 4, name="Sachin", age=21)
# 1
# (2, 3, 4) - args becomes a tuple
# {'name': 'Sachin', 'age': 21} - kwargs becomes a dictionary
```

`*args` functionality can be replicated in JS using rest operator as:

```jsx
// Only the last parameter can be a "rest parameter".
function myFun(a,  b, ...manyMoreArgs) {
  console.log("a", a)
  console.log("b", b)
  console.log("manyMoreArgs", manyMoreArgs)
}

myFun("one", "two", "three", "four", "five", "six")

// Console Output:
// a, one
// b, two
// manyMoreArgs, ["three", "four", "five", "six"]
```

Object Destructuring in JS

```jsx
const user = {
    id: 42,
    is_verified: true
};

const {id, is_verified} = user;
// here the name of variable should be same as the object's keys

console.log(id); // 42
console.log(is_verified); // true
```

Since the variable names should match the object's key, JS allows using aliases:

```jsx
const o = {p: 42, q: true};
const {p: foo, q: bar} = o;
 
console.log(foo); // 42 
console.log(bar); // true
```

Destructuring of argument passed as Object

```jsx
const info = {
	name: "Sachin",
	age: 21,
	profession: "Software Engineer"
}

function printDetails({name, age = 18, profession: job}) {
	console.log('name', name)
	console.log('age', age)
	console.log('job', job)
}

printDetails(info)
// name Sachin
// age 21
// job Software Engineer

// default age 18
// job as alias to profession
```

With so many rules with quite some similarities and subtle differences, remembering all these can seem to be overwhelming at first. I suggest not to mug up these syntax if you use either Python or JS or both, you can always bookmark this and read it later as and when you need to look up for something. 

References:

[Teclado - Destructuring in Python](https://blog.tecladocode.com/destructuring-in-python/)

[MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)

[Programiz - Python Args and Kwargs](https://www.programiz.com/python-programming/args-and-kwargs)

Thanks for reading. Stay tuned!!