spread and rest operators

spread and rest operators

1 The difference between spread and rest

Both spread and rest operators are in the form of...+variable/parameter. Whether it is spread or rest depends on the context.

1.spread

When used in an iterator, it is the spread operator:

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
console.log([1, ...[2, 3, 4], 5])
//[1,2,3,4,5]
function add(x, y) {
  return x + y;
}

const numbers = [4, 38];
add(...numbers) // 42
  1. rest When used to define the parameters of a function, it is the rest operator:
function push(...items) {
    console.log(items);
}
let a = 4;
push(a, 1, 2, 3)
//[4,1,2,3]

Rest is mainly to convert multiple parameters of the function into an array, and can only be placed in the last position of the function parameter, otherwise, such as (array,...items,other) will report an error.

And the emergence of rest, the arguments that are no longer recommended for use have completely come to an end.

(function fn(...args) {
console.log(args.join());
console.log([...arguments].join());//Usage of spread form
})([1,2,3]);
//>> 1,2,3
//>> 1,2,3

3. Usage example

3.1 Add attributes

Clone an object while adding additional properties to the (shallow) copy object. In this example, the user is (shallowly) copied and the password attribute is added to userWithPass.

const user = { id: 10, name: 'bobo'}
const userWithPass = { ...user, password: 'Password!' }

user //>> { id: 100, name: 'Howard Moon' }
userWithPass //>> { id: 10, name: 'bobo', password: 'Password!' }

3.2 Object merger

const part1 = { id: 10, name: 'bobo' }
const part2 = { id: 10, password: 'Password!' }

const user1 = { ...part1, ...part2 }
//>> { id: 10, name: 'bobo', password: 'Password!' }

Combine two objects into a new object:

const partial = { id: 100, name: 'Howard Moon' }
const user = { ...partial, id: 100, password: 'Password!' }

user //>> { id: 100, name: 'Howard Moon', password: 'Password!' }

3.3 Exclude object attributes** You can use the rest operator to delete attributes. In the following example, the password is deleted and the rest of the attributes are returned as rest.

const noPassword = ({ password, ...rest }) => rest
const user = {
  id: 10,
  name: 'bobo',
  password: 'Password!'
}

noPassword(user) //>> { id: 10, name: 'bobo' }

3.4 Dynamically exclude attributes

The function accepts a prop as a parameter. Using the calculated object attribute name, the attribute can be dynamically deleted from the clone.

const user1 = {
  id: 10,
  name: 'bobo',
  password: 'Password!'
}
const removeProperty = prop => ({ [prop]: _, ...rest }) => rest
//                     ----       ------
//                          \   /
//                dynamic destructuring

const removePassword = removeProperty('password')
const removeId = removeProperty('id')

removePassword(user1) //>> { id: 10, name: 'bobo' }
removeId(user1) //>> { name: 'bobo', password: 'Password!' }

3.5 Sort attributes

Sometimes the properties are not arranged in the order we need. Using some tricks, we can push attributes to the top of the list, or move them to the bottom. To move id to the first position, add id: undefined to the front of the new Object before extending the object.

const user3 = {
  password: 'Password!',
  name: 'bobo',
  id: 30
}

const organize = object => ({ id: undefined, ...object })
//                            -------------
//                          /
//  move id to the first property

organize(user3)
//>> { id: 30, password: 'Password!', name: 'bobo' }

To move password to the last attribute, deconstruct password from the object. Then reset the password attribute after using the Rest operator.

const user3 = {
  password: 'Password!',
  name: 'bobo',
  id: 30
}

const organize = ({ password, ...object }) =>
  ({ ...object, password })
//              --------
//             /
// move password to last property

organize(user3)
//>> { name: 'bobo', id: 30, password: 'Password!' }