函数参数
特征:
ECMAScript函数既不关心传入的参数个数,也不关心这些参数的数据类型。
定义函数时要接收两个参数,并不意味着调用时就传两个参数。
原因:
·因为ECMAScript函数的参数在内部表现为一个数组。
·函数被调用时总会接收一个数组,但函数并不关心这个数组中包含什么。
·传进函数的每个参数值都被包含在arguments对象((类数组)中。
1.arguments对象
①一个类数组对象(但不是Array的实例),因此可以使用中括号语法访问其中的元素。
·如,第一个参数是arguments[0],第二个参数是arguments[1]。
②要确定接收到的参数个数,可以访问
arguments.length 属性。
function likes(name, fav1, fav2) {
console.log(`${name}喜欢${fav1}、${fav2}。`);
let output = `${name}喜欢`;
let argCount = arguments.length;
for (let i = 1; i < argCount - 1; i++) {
output += `${arguments[i]}、`;
}
output += `${arguments[argCount - 1]}。`;
console.log(output);
}
likes("小明", "读书", "篮球");
2.参数默认值
比较以下两段代码
function f1(name, age) {
name = name ? name : "User";
age = age ? age : 0;
console.log(name, age);
}
f1();
f1("Tom");
function f2(name = "User", age = 0) {
console.log(name, age);
}
f2();
f2("Tom");
前者为ES5语法,后者为ES6写法。
3.扩展参数
分析以下代码
function sum() {
let r = 0;
for (let i = 0; i < arguments.length; i++) {
r += arguments[i];
}
return r;
}
let nums = [1, 2, 3, 4, 5];
console.log(sum.apply(null, nums));
console.log(sum(...nums));
4.剩余参数
分析以下下代码
function sum1(name) {
let r = 0;
for (let i = 1; i < arguments.length; i++) {
r += arguments[i];
}
console.log(`${name}总分为:${r}。`);
}
sum1("Tom", 80, 90, 100);
function sum2(name, ...scores) {
let r = scores.reduce((x, y) => x + y, 0);
console.log(`${name}总分为:${r}。`);
}
sum2("Tom", 80, 90, 100);
5.常见问题
function sum1() {
return Array.from(arguments).reduce((x, y) => x + y, 0);
}
let sum2 = () => {
return Array.from(arguments).reduce((x, y) => x + y, 0);
};
console.log(sum1(1, 2, 3), sum2(1, 2, 3));
箭头函数不支持arguments对象。
let sum3 = (...nums) => {
return nums.reduce((x, y) => x + y, 0);
};
console.log(sum3(1, 2, 3));
箭头函数支持剩余函数。
function f1(x, y, ...nums) {
console.log(arguments);
console.log(nums);
}
f1(1, 2, 3, 4, 5, 6);
f1(1, 2);
arguments对象包含了剩余参数值。
剩余参数没有接收到实参时,为空数组。
function f2(x, ...nums, y) {
console.log(nums);
console.log(y);
}
f2(1, 2, 3, 4, 5);
剩余参数必须位于参数列表的末尾。