函数的扩展
ES6增加了很多函数语法糖,使得JavaScript的编写更为简练。
函数参数的默认值
ES6中可以为函数配置默认参数。
示例
示例1
// ES5 var x = 1; function test(y) { y = y || x; }; // ES6 var x = 1; function test(y = x) {...}; test();
示例2
// ES6 var x = 1; function test(x, y = function(){ x = 2; console.log(x); // 2 }) { var x = 3; y(); console.log(x); // 3 } test(); console.log(x); // 1
注意事项
- 如果有多个参数的情况下,推荐的做法是把需要设置默认值的参数放到最后
- 每个函数都有个length方法,该方法返回没有设置默认值的参数个数
- 在ES6中引入了块级作用域的概念,在示例2中(当默认参数是函数时),一共有三个作用域空间:
- 全局作用域
- 函数作用域
- ES6新引入的有条件的参数立即作用域
对于全局与函数作用域,这两个概念相信大家不会陌生,在ES5中由于没有默认参数的概念,也就更没有默认参数为函数的情况,所以ES5中参数与函数共享函数作用域。在ES6中当函数有默认参数时,为了存储这些参数ES6会定义一个立即作用域,并且这个作用域不会与函数作用域共享。
- “立即”:ECMAScript在每次函数调用的执行期才会计算默认值,计算完毕后,这个作用域就会被销毁
- “有条件”:ES6中的函数没有默认参数时,就不会创建这个参数立即作用域的
引入参数立即作用域的原因是为了不污染双方函数的变量环境,清晰逻辑,各管各互不影响,比如构成闭包的时候。 如:
var x = 1; function test(x, y = function(){ var x = 2; return x; }) { var x = 3; return y(); } test(); // 2 这里的默认参数的y函数构成一个闭包需要返回y函数内部的x值,如果没有参数y函数与test函数是共享作用域的,这时test函数对x的重新赋值会影响到y函数的内部x值,这样输出的就是test函数中重新赋值的3。
rest参数
ES6引入rest运算符(…),创建可变参数,一个参数代表多个参数。
示例
function sum (results, ...values) { values.forEach((value) => results += value); return results; } sum(0,1,2,3,4,5,6) // 21
注意事项
- 需要使用rest参数时应该将这个参数放到最后
- 函数的length属性不包括rest参数
扩展运算符(spread)
spread,将一个参数展开为多个参数,与rest相反,多个参数代表为一个参数。
示例
var a = [1, 2, 3]; var b = [4, 5, 6, 7, 8]; var number = [ ...a, ...d]; // [1, 2, 3, 4, 5, 6, 7, 8] [...'hello'] // [ "h", "e", "l", "l", "o" ]
箭头函数
arrow(箭头函数)ES6新引入的定义函数的方式。
示例
// 循环体里就是一个箭头函数 function sum (results, ...values) { values.forEach((value) => results += value); // 或者 values.forEach((value) => {results += value;}); return results; }
箭头函数使得函数的定义变得十分简洁,有很多代码可以用更少的行来编写,使得代码变得十分精练。
注意事项
- 箭头函数的this对象式固定的,不像传统函数那样可变(谁调用this就是谁),箭头函数的this是开始定义时所在的对象
- 箭头函数不能当成构造函数使用
- 不可以使用arguments对象,也不能使用yield命令