第十章,函数
函数表达式,及箭头函数
很大程度上,箭头函数实例化的函数对象与正式的函数表达式
创建的函数对象行为是相同的。任何可以使用函数表达式的地方,都
可以使用箭头函数
如果只有一个参数,那也可以不用括号。只有没有参数,或者多
个参数的情况下,才需要使用括号:
// 以下两种写法都有效
let double = (x) => { return 2 * x; };
let triple = x => { return 3 * x; }; // 没有参数需要括号
let getRandom = () => { return Math.random(); }; // 多个参数需要括号
let sum = (a, b) => { return a + b; }; // 无效的写法:
let multiply = a, b => { return a * b; };
小结:单个参数可以省略括号,没有参数,和多个参数都需要括号
函数名
- 因为函数名就是指向函数的指针,所以它们跟其他包含对象指针的变量具有相同的行为。这意味着一个函数可以有多个名称,如下所示
function sum(num1, num2) {
return num1 + num2;
}
console.log(sum(10, 10)); // 20
let anotherSum = sum;
console.log(anotherSum(10, 10));
// 20 sum = null;
console.log(anotherSum(10, 10)); // 20
小结:上面定义了一个sum()函数,然后声明一个变量anotherSum,并且讲他的值设置为sum,赋值时候sum没有带括号,所以会访问函数的指针,而不会执行,所以anotherSum和sum指向同一个函数,调用anotherSum也可以返回结果,并且改变sum并不会影响anotherSum的调用,
小计:JS中所有函数都会暴露一个只读的name属性,这个属性保存的就是一个函数标识符,即使函数没有名称,也会显示成空字符串,如果Function构造的,则会标识成 「anonymous」
例子2:
function foo() {}
let bar = function() {};
let baz = () => {};
console.log(foo.name); // foo
console.log(bar.name); // bar
console.log(baz.name); // baz
console.log((() => {}).name); //(空字符
串)
console.log((new Function()).name); // anonymous
理解参数
JS函数的参数:是数组形式,所以会有以下特性
- 没有限制个数
- 不关心数据类型
- 定义数可以不遵循
使用function定义非箭头函数时候,可以在函数内部访问「arguments」(函数接受的参数数组),arguments对象是一个类数组对象,但不是Array的实例,因此访问可以用arguments[0],这种方式访问参数,arguments.length可以确定传进来了几个参数
例子1:
function doAdd(num1, num2) {
if (arguments.length === 1) {
console.log(num1 + 10);
} else if (arguments.length === 2) {
console.log(arguments[0] + num2); }
}
小结:这个例子把arguments.length和数组取值的方法用进了函数判断中,当一个参数时候,执行吧第一个参数加10,两个参数的时候,则让两个参数相加
- 「没有重载」 :JS中定义两个同名函数,后定义的会覆盖先定义的,
- 「扩展参数」:对可迭代的参数使用扩展运算符,可将迭代返回的每个值单独传入
let values = [1, 2, 3, 4];
function getSum() {
let sum = 0;
for (let i = 0; i < arguments.length; ++i) {
sum += arguments[i];
}return sum;
}
console.log(getSum(...values)); // 10
console.log(getSum(-1, ...values)); // 9
小结:参数是一个数组时候,使用扩展运算符,等于依次传入数组中的参数,而且因为数组的长度已知,所以并不会影响他的前后传参,依旧可以
- 收集参数:可以使用扩展操作符把不同长度的独立参数组合为一个数组。收集参数的前面如果还有命名参数,则只会收集其余的参数;如 果没有则会得到空数组。因为收集参数的结果可变,以只能把它作 为最后一个参数
// 不可以
function getProduct(...values, lastValue){
}
// 可以
function ignoreFirst(firstValue, ...values) {
console.log(values);
}
ignoreFirst(); // []
ignoreFirst(1); // []
ignoreFirst(1,2); // [2]
ignoreFirst(1,2,3); // [2, 3]
函数声明和函数表达式
「区别」:函数声明在引擎执行代码前,会先读取,并且在执行上下文中生成定义,但是表达式,必须执行到那一行,才会执行上下文中生成函数定义
「函数作为值」:
- 因为函数名在JS中是变量,所以函数可以在任何使用变量的地方使用,这意味着不仅可以把函数作为参数传给另一个函 数,而且还可以在一个函数中返回另一个函数
function callSomeFunction(someFunction, someArgument) {
return someFunction(someArgument);
}
function add10(num) {
return num + 10;
}
let result1 = callSomeFunction(add10, 10);
console.log(result1); // 20
function getGreeting(name) {
return "Hello, " + name;
}
let result2 = callSomeFunction(getGreeting, "Nicholas");
console.log(result2); // "Hello, Nicholas"
小结:上面定义一个函数,第一个参数把第二个参数作为参数使用,
本文使用 mdnice 排版