Default Parameters(函数默认的参数值)
es5中怎么处理函数参数的默认值?
参数的默认值通常写在函数体重,很麻烦,维护复杂,代码冗余
function f(x, y, z) {
if (y === undefined) {
y = 7
}
if (z === undefined) {
z = 42
}
return x + y + z
}
console.log(f(1, 8, 43));
es6是如何做的呢?
有默认值的参数往后写(y,z),函数参数是从左到右解析,如果没有默认值会被解析成undefined
function f2(x, y = 7, z = 42) {
return x + y + z;
}
console.log(f2(1, 8, 43));
// 如果要改z值,而不改y值呢
// 如果想让具体某个参数使用默认值,可以使用undefined赋值
console.log(f2(1, undefined, 43));
// 参数赋值支持参数的逻辑运算进行赋值
function f3(x, y = 7, z = x + y) {
return x * 10 + z;
}
在函数内部,如何知道函数传入了几个参数?
- es5的做法,是用arguments
function f4(x, y = 7, z = x + y) {
console.log(arguments.length, '000000');
console.log(Array.from(arguments), '000000');
return x * 10 + z;
}
console.log(f4(1, undefined));
- es6不允许再使用arguments,用Function.length获取的是第一个默认参数前面的变量数
function f5(x, y = 7, z = x + y) {
console.log(f5.length, '11111'); // 1
return x * 10 + z;
}
console.log(f5(1, 2, 3));
Rest parameter(怎么处理不确定参数?)
es5中怎么处理不确定参数的问题?
- 使用arguments
function sum() {
let num = 0;
// es5
// Array.prototype.forEach.call(arguments, function (item) {
// num += item * 1
// })
Array.from(arguments).forEach(function (item) {
num += item * 1
})
return num;
}
console.log(sum(1,2,7));
es6是如何做的呢
function sum2(...nums) {
let num = 0;
// Rest parameter
nums.forEach(function (item) {
num += item * 1
})
return num
}
console.log(sum(1,2,8));
function sum3(base, ...nums) {
let num = 0;
// Rest parameter
nums.forEach(function (item) {
num += item * 1
})
return base * 2 + num
}
arguments不是数组,所以不能直接使用数组的原生API如forEach,而Rest Parameter是数组,可以直接使用数组的原生API
Spread Operator(rest参数的逆运算)
Spread Operator和Rest Parameter是形似但意义相反的操作符,简单来说Rest Parameter是把不定的参数”收敛“到数组,而Spread Operator是把固定的数组内容”打散“到对应的参数
function sum(x = 1, y = 2, z = 3) {
return x + y + z;
}
let data = [4,5,6]
// es5
console.log(sum.apply(this,data));
// es6
console.log(sum(...data));
Rest Parameter用来解决函数不确定的场景,Spread Operator用来解决已知参数集合应用到固定参数的函数上。
Arrow Function(箭头函数)
es6中的箭头函数是什么?
- 如果只有一个参数,可以省略括号,如果大于一个参数一定要记得带括号
返回值需要注意什么?
- 如果返回值是表达式,可以省略return和{}
let pow = x => x*x
- 如果返回值是字面量对象,一定要用小括号括起来
let person = name => ({
age:20,
addr:'beijing'
})
箭头函数对this的处理还有什么妙用?
- 箭头函数没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数,和new一起使用会抛出错误
let Foo = () => {}
let foo = new Foo(); // TypeError: Foo is not a constructor
- 在箭头函数出现之前,每一个新函数根据它是如何被调用的来定义这个函数的this值
- 箭头函数不会创建自己的this,它只会从自己的作用域链上一层继承this。
- 箭头函数没有prototype属性。
let Foo = () => {};
console.log(Foo.prototype); // undefined