📆 Thời gian:
🕐 6 phút đọc
The spread is the operator that allows us to expand iterables into individual elements.
The rest is the operator we use to represent an indefinite number of arguments in an array.
Both are written using the three dots ..., but you'll see that it's easy to identify when it's a spread and when it's a rest! At the end, there's also a good tip for you!
The spread allows us to combine two or more arrays, maintaining a concise and clean language.
Let's have some coffee? ☕️ Consider the two arrays below:
const coffee = ['coffee', 'water'];
const spices = ['cinnamon', 'nutmeg', 'cardamom'];
We can use the spread to mix the ingredients into a single array:
const coffeeReady = [...coffee, ...spices];
console.log(coffeeReady)
// output:
// ['coffee', 'water', 'cinnamon', 'nutmeg', 'cardamom'];
Simple! Much better than writing item by item from each of the two arrays to form coffeeReady.
Important:
1. Changes in coffee will NOT affect coffeeReady!
To better understand: when we make a copy, we can either create a new reference to the original value or just copy the value. Creating a new reference is simply creating a variable that will point to the same location in memory where the original value is.
If we had created a new reference, any changes in coffee would change coffeeReady and vice versa. But what we did with the spread was to copy only the value, which in turn will be stored in another location in memory. Thus, changes in one array will not affect the other.
However, some details could change this picture! That's because...
2. The spread only creates a shallow copy!
This means that, depending on the data contained in coffee, some changes could indeed alter coffeeReady! If coffee contained some non-primitive value, the computer would have created a reference to the values in memory. So, any change in one array would affect the other, since both would be storing a reference to the same location in memory. See below:
const a = [1, [2, 3]];
// [2, 3] is an array nested in a, and therefore
// it is a non-primitive value
const b = [4, 5, 6];
const c = [...a, ...b];
console.log(c);
// output: [1, [2, 3], 4, 5, 6]
a[0] = 11;
a[1][0] = 22;
console.log(c);
// output: [1, [22, 3], 4, 5, 6]
See above that changing a[0] did not affect c, because we changed a primitive value. In other words, a[0] and c point to equal values, but they are in different locations in memory. However, changing a[1][0] modified c, because we changed the value to which both a[1][0] and c point.
We can also merge objects into one using the spread:
const myParents = {
fathersName: 'Michael',
mothersName: 'Louise'
};
const mySiblings = {
brothersName: 'Philip',
sistersName: 'Lara'
};
const myFamily = { ...myParents, ...mySiblings };
console.log(myFamily);
/* output:
{
fathersName: 'Michael',
mothersName: 'Louise',
brothersName: 'Philip',
sistersName: 'Lara'
}
*/
However, it is important to remember that the spread does not clone identical properties! Below we have two objects with brothersName:
const myParents = {
fathersName: 'Michael',
mothersName: 'Louise',
brothersName: 'Gabriel'
};
const mySiblings = {
brothersName: 'Philip',
sistersName: 'Lara'
};
const myFamily = { ...myParents, ...mySiblings };
console.log(myFamily);
/* output:
{
fathersName: 'Michael',
mothersName: 'Louise',
brothersName: 'Philip',
sistersName: 'Lara'
}
*/
Note that the final object does not inherit both brothersName keys. In fact, only one prevails, which is from the second object.
Got the idea so far? If we can merge arrays and also objects, that means we can also copy them individually:
// creating a shallow copy of coffee:
const coffee = ['coffee', 'water'];
const coffeeCopy = [...coffee];
console.log(coffeeCopy)
// output:
// ['coffee', 'water'];
// creating a shallow copy of mySiblings:
const mySiblings = {
brothersName: 'Philip',
sistersName: 'Lara'
};
const myFamily = {
fathersName: 'Michael',
mothersName: 'Louise',
...mySiblings
};
// Now we can treat brothersName and sistersName as
// a property of myFamily:
console.log(myFamily.brothersName)
// output: Philip
It is also possible to use the spread to turn a string into an array. This allows us to have more flexibility when manipulating strings, since we will be able to apply array methods to strings:
const str = 'coffee';
const letters = [...str, 's.', '☕️'];
console.log(letters);// ["c", "o", "f", "f", "e", "e", "s.", "☕️"]
As mentioned above, the rest operator is used to pack elements into an array. You'll see that the rest operator is a great ally when dealing with many values or an uncertain number of values.
The rest operator allows us to represent an indefinite number of arguments as an array.
const order = function(beverage, ...otherIngredients) {
console.log(beverage);
console.log(otherIngredients);
};
order('green tea', 'milk', 'brown sugar');
// output:
// green tea
// ['milk', 'brown sugar']
Note that this allows us to call the same function with more arguments, as the rest operator will put them all in the otherIngredients array:
const order = function(beverage, ...otherIngredients) {
console.log(beverage);
console.log(otherIngredients);
};
order('green tea', 'milk', 'brown sugar', 'mint', 'tonka');
// output:
// green tea
// ['milk', 'brown sugar', 'mint', 'tonka']
🍵 An important detail is that the rest must be the last parameter in the function! If we wrote function(...otherIngredients, beverage) the computer wouldn't know when to stop and this code would generate an error.
Rest and spread are also widely used in destructuring. If you don't know what that is yet, I suggest my other two articles here: array destructuring and object destructuring.
Using rest:
const [a, b, ...others] = [1, 2, 3, 4, 5];
console.log(a, b, others);
// output: 1 2 [3, 4, 5]
Now, take this tip so you don't confuse rest with spread here: the rest is on the left side of = and the spread is on the right side of =.
...rest = ☕️
🍵 = ...spread
Thanks for making it this far! I hope this post has helped you! Thoughts? Please, comment below!
Reference: https://dev.to/baroblesvi/spread-vs-rest-operators-in-javascript-45f3
0
0
0
0
javascript, array javascript