ES6 Function

箭头函数

使用“箭头”(=>)定义函数。

var f = v => v;

// ES 5
var f = function(v) {
  return v;
};

使用注意事项

参数默认值定义

使用默认参数,在函数体的检查就不再需要了

function multiply(a, b = 1) {
    return a*b;
}

multiply(5); // 5

剩余参数(rest)

剩余参数语法允许将不确定数量的参数表示为数组。

function multiply(multiplier, ...theArgs) {
    return theArgs.map(x => multiplier * x);
}

var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]

扩展运算符...

它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

应用:

name属性

这个属性早就被浏览器广泛支持,但是直到ES6,才将其写入了标准。
* 如果将一个匿名函数赋值给一个变量,ES5的name属性,会返回空字符串,而ES6的name属性会返回实际的函数名

```javascript
var func1 = function () {};

// ES5
func1.name // ""

// ES6
func1.name // "func1"
```

Bound Function的prototype

function的length属性是可配置的

var fn = function(a, b) {};

var desc = Object.getOwnPropertyDescriptor(fn, "length");
if (desc.configurable) {
    Object.defineProperty(fn, "length", { value: 1 });
    fn.length === 1;
}

尾调用优化

第一次明确规定,所有ECMAScript的实现,都必须部署“尾调用优化”,这就是说,在ES6中,只要使用尾递归,就不会发生栈溢出,相对节省内存。

// 尾调用
function f(x){
    return g(x);
}
// 尾递归
function factorial(n, total) {
    if (n === 1) return total;
    return factorial(n - 1, n * total);
}

尾调用和尾递归优化后的调用栈深度始终为1,因为在进行尾部函数调用的时候前面的函数调用环境已经销毁,节省内存开销,不会发生栈溢出。