1. Function Parameter Default Values
Previously, we often wrote code like this:
function doS(e) {
e = e | window.e;
//doSomeThing with e
}This method of setting default values for function parameters has a drawback: if the passed-in parameter’s boolean equivalent is false, such as an empty string or 0, it can lead to unexpected behavior.
Therefore, if we still want the above code to produce the correct result, we need to add another check for e to determine if it has been assigned a value.
This can be cumbersome, so ES6 introduced a new method, as follows:
function doS(e = window.e) {
//doSomeThing with e
}Not only does this significantly shorten the code, but it also greatly improves readability. Anyone reading the code can immediately see which parameters have default values.
Furthermore, setting default values is very flexible:
function get(url,{body='',method='GET'){
console.log(method);
}In the code above, the second parameter passed in is an object, and we can set default values for its properties.
You can even set nested default values.
fetch(url, { method = 'GET' } = {}){
console.log(method);
}In the code above, when calling the fetch function, if the second parameter is omitted, it defaults to an empty object; if the second parameter is included, its method property defaults to GET.
Parameter default value settings also support destructuring assignment:
function ha({ x, y = 5 }) {
console.log(x, y);
}
ha(); //TypeError: Cannot read property 'x' of undefined
ha({}); //undefined 5
ha({ x: 1 }); //1 5
ha({ x: 1, y: 2 }); //1 2Parameters with default values must be placed at the end of the parameter list. This is because once a default value is set, the parameter can be omitted, and only if it’s at the end can the function determine which parameter was omitted.
If undefined or null is passed to a parameter with a default value, the former will trigger the default value, while the latter will not.
function a(b = 1, c = 2) {
console.log(b, c);
}
a(undefined, null);
//1 nullIt’s important to note that if default values are set, the function’s length property can be inaccurate.
> (function a(a,b){}).length
2
> (function b(a,b,c){}).length
3
> (function c(a,b,c=1){}).length
2
> (function e(a,b=1,c=1){}).length
1As you can see, when no default values are set, the function’s length equals the number of its parameters. However, after setting default values, its length equals the number of parameters without default values.
2. Rest Parameters
Rest parameters are used to capture excess arguments passed to a function, thus avoiding the need for the arguments object.
function add(...values) {
let sum = 0;
values.forEach(function(value){
sum += value;
});
return sum;
}
> add(1,2,3,4,5)
15As you can see, this function can return the sum of the passed-in arguments. Also, note that a rest parameter is essentially an array, so all array methods can be used on it, which is why forEach in the above code works.
It’s important to note that, similar to default parameters, rest parameters must be at the end of the parameter list. Also, the function’s length property does not include rest parameters.
(function (a) {})
.length(
// 1
function (...a) {},
)
.length(
// 0
function (a, ...b) {},
).length; // 13. Spread Operator
The spread operator, denoted by three dots (...), can be thought of as the inverse of the rest parameter. It can convert an array into a comma-separated sequence of arguments.
> let array = [1,2,34];
> console.log(...array)
1 2 34
> console.log(11,22,...array,4)
11 22 1 2 34 4This operator is primarily used in function calls.
function push(array, ...items) {
array.push(...items);
}
function add(x, y) {
return x + y;
}
var numbers = [4, 38];
add(...numbers); // 42In the code above, both
array.push(...items)andadd(...numbers)are function calls, and both use the spread operator. This operator transforms an array into a sequence of arguments.
Because the spread operator can expand arrays, the
applymethod is no longer needed to convert an array into function arguments.
// ES5的写法
function f(x, y, z) {}
var args = [0, 1, 2];
f.apply(null, args);
// ES6的写法
function f(x, y, z) {}
var args = [0, 1, 2];
f(...args);A practical example:
> let a=[1,23,12,31,23,12,31,23,123,12,31,24,]
'use strict'
> Math.max(...a)
123
//ES5要实现同样的功能则需要
Math.max.apply(null,a);The spread operator can simplify many ES5 patterns:
```javascript
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
// ES5
list.push.apply(list, [3, 4])
// ES6
list.push(...[3, 4])
// ES5
list = [1,2,3,4]
var a = list[0], rest = list.slice(1)
a = 1,rest = [2,3,4]
// ES6 这里是用到了解构赋值
var [a, ...rest] = list
a = 1,rest = [2,3,4]
// ES5
new (Date.bind.apply(Date, [null, 2015, 1, 1]))
// ES6
new Date(...[2015, 1, 1]);
```It’s important to note that if the spread operator is used for array assignment, it must be placed at the end of the array literal; otherwise, it will throw an error. (This makes sense, as how else would the program know the length of the spread operator’s expansion?).
The spread operator can convert a string into an array (as can Array.from()).
> [...'hello']
[ 'h', 'e', 'l', 'l', 'o' ]4. Arrow Functions
Basic Usage
Use ‘arrows’ to quickly define functions:
let fn = (f) => f;Equivalent to:
let fn = function (f) {
return f;
};When no parameters are needed, or when there is more than one parameter, use parentheses for the parameter part:
```javascript
var f = () => 5;
//等于
var f = function(){return 5};
var sum =(sum1,sum2) => num1 + num2;
//等于
var sum = function(sum1,sum2){
return sum1+sum2;
}
```In short, whatever follows the arrow is what the function will return. When the arrow function’s code block contains more than one statement, it needs to be enclosed in curly braces, and an explicit return statement must be used. Since curly braces are interpreted as a code block, if an arrow function needs to return an object, the object must be wrapped in parentheses; otherwise, it will be interpreted as a code block.
var sum = (num1, num2) => {
return num1 + num2;
};
var sum1 = (sumI) => ({ su1: "1", su2: "2" });Similarly, arrow functions can be combined with destructuring assignment.
let person = ({you,i}) => you + 'love' + i;
> person({you:'y',i:'i'})
'ylovei'
//等于
var person = function(obj){
return obj.you +'love'+obj.i;
}Points to Note for Usage Arrow functions have several important points to consider.
(1) The
thisobject inside the function body is bound to the object where it is defined, not where it is used.
(2) They cannot be used as constructors; that is, you cannot use the
newkeyword with them, otherwise, an error will be thrown.
(3) The
argumentsobject cannot be used; it does not exist within the function body. If you need similar functionality, you can use rest parameters instead.
(4) The
yieldkeyword cannot be used, therefore arrow functions cannot be used as Generator functions.
Among the four points above, the first one is particularly noteworthy. The
thisobject’s binding is usually mutable, but in arrow functions, it is fixed. The following code provides an example ofthisbeing bound to the object where it is defined.
Copyright
All code in this article is sourced from or adapted from:
阮一峰-ECMAScript 6 入门, and this article also adheres to the Attribution-NonCommercial License.
