前言
今天开始和大家一起系统的学习ES6+,每天3分钟,用一把斗地主的时间,重学ES6+,今天介绍的是函数的补充 展开语法
函数的默认参数
- 在ES6之前,我们编写的函数参数是没有默认值的,所以我们在编写函数时,如果有下面的需求:
- 传入了参数,那么使用传入的参数;
- 没有传入参数,那么使用一个默认值;
- 而在ES6中,我们允许给函数一个默认值:
代码演示
// ES5以及之前给参数默认值 /** * 缺点: * 1.写起来很麻烦, 并且代码的阅读性是比较差 * 2.这种写法是有bug */ function foo(m, n) { m = m || "aaa" n = n || "bbb" console.log(m, n) } // 1.ES6可以给函数参数提供默认值 function foo(m = "aaa", n = "bbb") { console.log(m, n) } // foo() foo(0, "")
函数默认值的补充
默认值也可以和解构一起来使用:
另外参数的默认值我们通常会将其放到最后(在很多语言中,如果不放到最后其实会报错的):
*但是JavaScript允许不将其放到最后,但是意味着还是会按照顺序来匹配;
另外默认值会改变函数的length的个数,默认值以及后面的参数都不计算在length之内了。
代码演示
// 1.对象参数和默认值以及解构 function printInfo({name, age} = {name: "why", age: 18}) { console.log(name, age) } printInfo({name: "kobe", age: 40}) // 另外一种写法 function printInfo1({name = "why", age = 18} = {}) { console.log(name, age) } printInfo1() // 2.有默认值的形参最好放到最后 function bar(x, y, z = 30) { console.log(x, y, z) } // bar(10, 20) bar(undefined, 10, 20) // 3.有默认值的函数的length属性 function baz(x, y, z, m, n = 30) { console.log(x, y, z, m, n) } console.log(baz.length) // 打印 4
函数的剩余参数
ES6中引用了rest parameter,可以将不定数量的参数放入到一个数组中:
- 如果最后一个参数是 ... 为前缀的,那么它会将剩余的参数放到该参数中,并且作为一个数组;
- 那么剩余参数和arguments有什么区别呢?
- 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参;
- arguments对象不是一个真正的数组,而rest参数是一个真正的数组,可以进行数组的所有操作;
- arguments是早期的ECMAScript中为了方便去获取所有的参数提供的一个数据结构,
- 而rest参数是ES6中提供 并且希望以此来替代arguments的;
- 剩余参数必须放到最后一个位置,否则会报错。
代码演示
function foo(...args, m, n) { console.log(m, n) console.log(args) console.log(arguments) } foo(20, 30, 40, 50, 60) // 报错 // Uncaught SyntaxError: Rest parameter must be last formal parameter // rest paramaters必须放到最后 // Rest parameter must be last formal parameter function foo(m, n = m + 1) { console.log(m, n) } foo(10);
展开语法
- 展开语法(Spread syntax):
- 可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开;
- 还可以在构造字面量对象时, 将对象表达式按key-value的方式展开;
- 展开语法的场景:
- 在函数调用时使用;
- 在数组构造时使用;
- 在构建对象字面量时,也可以使用展开运算符,这个是在ES2018(ES9)中添加的新特性;
- 注意:展开运算符其实是一种浅拷贝;
代码演示
const names = ["abc", "cba", "nba"] const name = "why" const info = {name: "why", age: 18} // 1.函数调用时 function foo(x, y, z) { console.log(x, y, z) } // foo.apply(null, names) foo(...names) //打印 abc cba nba foo(...name) // 打印 w h y // 2.构造数组时 const newNames = [...names, ...name] console.log(newNames) //打印 ['abc', 'cba', 'nba', 'w', 'h', 'y'] // 3.构建对象字面量时ES2018(ES9) const obj = { ...info, address: "广州市", ...names } console.log(obj) // 打印 {0: 'abc', 1: 'cba', 2: 'nba', name: 'why', age: 18, address: '广州市'} // 数组被展开