The spread operator (spread) is three points (…) . It is like the inverse of the REST argument, turning an array into a comma-separated sequence of arguments.


      
  1. console.log(... [ 1. 2. 3])
  2. / / 1 2 3
  3. console.log( 1. [ 2. 3. 4]. 5)
  4. // 1, 2, 3, 4, 5
  5. [...document.querySelectorAll( 'div')]
  6. // [<div>, <div>, <div>]
Copy the code


This operator is used primarily for function calls.



      
  1. function push(array, ... items) {
  2. array.push(... items);
  3. }
  4. function add(x, y) {
  5. return x + y;
  6. }
  7. var numbers = [ 4. 38];
  8. add(... numbers) / / 42
Copy the code

In the code above, array.push(… The items) and add (… Numbers), both function calls that use the extension operator. This operator turns an array into a sequence of arguments.

Extended operators can be used in conjunction with normal function parameters, making them very flexible.


      
  1. function f(v, w, x, y, z) {}
  2. var args = [ 0. 1];
  3. f( - 1. args, 2. [ 3]);
Copy the code


2 replaces the apply method for arrays

Because the extension operator can expand an array, the apply method is no longer needed to convert the array to a function parameter.


      
  1. // ES5
  2. function f(x, y, z) {
  3. // ...
  4. }
  5. var args = [ 0. 1. 2];
  6. f.apply( null, args);
  7. // ES6
  8. function f(x, y, z) {
  9. // ...
  10. }
  11. var args = [ 0. 1. 2];
  12. f(... args);
Copy the code


Here is a practical example of the extension operator replacing apply to simplify writing the largest element of an array using math.max.


      
  1. // ES5
  2. Math.max.apply( null[ 14. 3. 77])
  3. // ES6
  4. Math.max(... [ 14. 3. 77])
  5. / / is equivalent to
  6. Math.max( 14. 3. 77);
Copy the code

The code above shows that since JavaScript does not provide a function for finding the largest element of an array, you can only use the math.max function, which turns the array into a sequence of parameters and then evaluates the maximum. Now that you have the extension operator, you can use math.max directly.

Another example is adding an array to the end of another array using the push function.


      
  1. // ES5
  2. var arr1 = [ 0. 1. 2];
  3. var arr2 = [ 3. 4. 5];
  4. Array.prototype.push.apply(arr1, arr2);
  5. // ES6
  6. var arr1 = [ 0. 1. 2];
  7. var arr2 = [ 3. 4. 5];
  8. arr1.push(... arr2);
Copy the code

In the ES5 version of the code above, the arguments to the push method cannot be arrays, so we have to use the apply method to work around the push method. With the extension operator, you can pass an array directly to the push method. Here’s another example.


      
  1. // ES5
  2. new ( Date.bind.apply( Date[ null. 2015. 1. 1]))
  3. // ES6
  4. new Date(... [ 2015. 1. 1]);
Copy the code


Extend the application of operators

(1) Merge arrays

The extension operator provides a new way of writing array merges.


      
  1. // ES5
  2. [ 1. 2].concat(more)
  3. // ES6
  4. [ 1. 2. more]
  5. var arr1 = [ 'a'. 'b'];
  6. var arr2 = [ 'c'];
  7. var arr3 = [ 'd'. 'e'];
  8. // Merge array of ES5
  9. arr1.concat(arr2, arr3);
  10. // [ 'a', 'b', 'c', 'd', 'e' ]
  11. // Merge array of ES6
  12. [...arr1, ...arr2, ...arr3]
  13. // [ 'a', 'b', 'c', 'd', 'e' ]
Copy the code


(2) Combine with deconstruction assignment

Extension operators can be used in conjunction with destructuring assignments to generate arrays.


      
  1. // ES5
  2. a = list[ 0], rest = list.slice( 1)
  3. // ES6
  4. [a, ...rest] = list
  5. Here are some other examples.
  6. const [first, ...rest] = [ 1. 2. 3. 4. 5];
  7. first / / 1
  8. rest // [2, 3, 4, 5]
  9. const [first, ...rest] = [];
  10. first // undefined
  11. rest / / [] :
  12. const [first, ...rest] = [ "foo"];
  13. first // "foo"
  14. rest / / []
Copy the code

If an extension operator is used for array assignment, it must be placed in the last bit of the argument, otherwise an error will be reported.


      
  1. const [...butLast, last] = [ 1. 2. 3. 4. 5];
  2. / / an error
  3. const [first, ...middle, last] = [ 1. 2. 3. 4. 5];
  4. / / an error
Copy the code

(3) Return value of the function

JavaScript functions can only return one value, or arrays or objects if multiple values are required. Extension operators provide a workaround around this problem.


      
  1. var dateFields = readDateFields(database);
  2. var d = new Date(... dateFields);
Copy the code

The code above takes a row from the database and passes it directly to the Date constructor by extending the operator.

(4) String

Extension operators can also turn strings into true arrays.


      
  1. [... 'hello']
  2. // [ "h", "e", "l", "l", "o" ]
Copy the code

One important benefit of the above notation is that it correctly recognizes 32-bit Unicode characters.


      
  1. 'x\uD83D\uDE80y'.length / / 4
  2. [... 'x\uD83D\uDE80y'].length / / 3
Copy the code

In the first version of the code above, JavaScript recognizes 32-bit Unicode characters as two characters, which is not a problem with the extension operator. Therefore, a function that correctly returns the length of a string can be written as follows.


      
  1. function length(str) {
  2. return [...str].length;
  3. }
  4. length( 'x\uD83D\uDE80y') / / 3
Copy the code

This problem applies to all functions that operate on 32-bit Unicode characters. Therefore, it is best to overwrite everything with extension operators.


      
  1. let str = 'x\uD83D\uDE80y';
  2. str.split( ' ').reverse().join( ' ')
  3. // 'y\uDE80\uD83Dx'
  4. [...str].reverse().join( ' ')
  5. // 'y\uD83D\uDE80x'
Copy the code

In the code above, the reverse operation of the string would not be correct without the extension operator.

(5) Objects that implement the Iterator interface

Any object of the Iterator interface can be converted to a true array using the extension operator.


      
  1. var nodeList = document.querySelectorAll( 'div');
  2. var array = [...nodeList];
Copy the code

In the above code, the querySelectorAll method returns a nodeList object. It’s not an array, it’s an array-like object. In this case, the extension operator can turn it into a true array because the NodeList object implements the Iterator interface.

For array-like objects that do not have an Iterator interface deployed, the extension operator cannot turn them into true arrays.


      
  1. let arrayLike = {
  2. '0': 'a'.
  3. '1': 'b'.
  4. '2': 'c'.
  5. length: 3
  6. };
  7. // TypeError: Cannot spread non-iterable object.
  8. let arr = [...arrayLike];
Copy the code

In the above code, arrayLike is an array-like object, but without the Iterator interface deployed, the extension operator will report an error. At this point, you can turn an arrayLike into a real Array using the array. from method instead.

(6) Map and Set structures, Generator functions

An extension operator internally calls the Iterator interface of a data structure, so any object that has an Iterator interface can use an extension operator, such as a Map structure.


      
  1. let map = new Map([
  2. [ 1. 'one'].
  3. [ 2. 'two'].
  4. [ 3. 'three'].
  5. ]);
  6. let arr = [...map.keys()]; / / [1, 2, 3]
Copy the code

When the Generator function runs, it returns an traverser object, so extension operators can also be used.


      
  1. var go = function* (){
  2. yield 1;
  3. yield 2;
  4. yield 3;
  5. };
  6. [...go()] / / [1, 2, 3]
Copy the code

In the above code, the variable go is a Generator function that returns an traverser object. Executing the extension operator on this traverser object converts the values of the internal traversal into an array.


An error is reported if you use the extension operator on an object that does not have an iterator interface.


      
  1. var obj = { a: 1. b: 2};
  2. let arr = [...obj]; // TypeError: Cannot spread non-iterable object
Copy the code