本节目标
- 掌握函数定义的4种方式:常规函数、匿名函数、箭头函数、构造器函数。
- 掌握函数不定参数的声明方式。
- 了解js语言中的内置函数。
内容摘要
本篇介绍了js中函数定义的4种方式:常规函数、匿名函数、箭头函数、构造器函数,以及不定参数的声明方式 …args。
阅读时间30~40分钟。
函数简介和使用
基本上所有的高级语言都支持函数,JavaScript也不例外。JavaScript的函数不但是“头等公民”,而且可以像变量一样使用,也是一种数据类型,具有非常强大的抽象能力。
js中定义函数有4种方式:
1. 常规函数
2. 匿名函数
3. 箭头函数
4. 构造器函数
下面依次对每个函数进行讲解。
常规函数
函数声明通过 function 关键词进行声明,有三个要素:函数名、函数参数、返回值。
语法结构:
function 函数名([参数1, 参数2, ...]) {
代码块
[return 返回值]
}
其中:
函数名,表示函数的名字,js中一般采用驼峰命名法。
参数可选,可以不传参数,也可以传入若干个参数。
return为可选,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。
函数声明完成之后,正常是给其他地方调用的,调用语法如下:
没有返回值: 函数名(参数1, 参数2, ...)
有返回值:let 变量名 = 函数名(参数1, 参数2, ...)
函数名.call()
函数名.apply()
其中:
有返回值的函数,一般可以用变量进行接收,也可以直接使用。
call和apply是函数对象的方法,也可以起到调用函数的目的。
示例1,声明一个函数,打印:Hello function:
function print() {
console.log("Hello function");
}
这边我们尝试查看 print 函数的类型:
console.log(type of print); // function
是一个函数类型,具体来说是一个函数对象,正因为是对象,所以可以有属性和方法,call和apply就是其中的方法。
下面调用函数:
print(); // 常规调用
print.call(); // call调用
print.apply(); // apply调用
其中:
call和apply也是调用函数的两种方式,这种方式可以改变this的指向。我们在面向对象章节会再细讲。
注意:
这边这个函数没有返回值,对于没有返回值的函数,如果用一个变量接收,那么就是undefined。
let result = print();
console.log(result); // undefined
示例2,声明一个函数,传入三角形的底和高,返回三角形的面积。
function area(d, h) {
return d * h / 2;
}
声明好后,调用:
let result = area(10, 5);
console.log(result); // 25
console.log(area.call(null, 10, 5)); // call调用
console.log(area.apply(null, [10, 5])); // apply调用
其中:
call方法,第一个参数表示传入的对象,后面罗列area方法需要的参数。
apply方法,第一个参数表示传入的对象,后面用数组罗列area方法需要的参数。
匿名函数
上面声明的函数有显式的名字,js中也可以声明没有名字的函数,俗称匿名函数。
只是如果函数如果没有名字,要怎么调用呢?所以需要将匿名函数赋值给一个变量。
语法:
let 变量名 = function([参数1, 参数2, ...]){
代码块
[return 返回值]
}
其中:
匿名函数没有函数名,但是匿名函数可以赋值给变量,所以可以通过变量调用该函数。
示例1,声明一个匿名函数,打印:Hello,我是一个匿名函数,可以通过变量名对我进行调用。
let printHello = function () {
console.log("Hello,我是一个匿名函数,可以通过变量名对我进行调用。");
};
调用该函数:
printHello();
既然f是一个变量,那应该有数据类型,我们通过 typeof 查看f的数据类型:
console.log(typeof printHello); // function
可以发现函数 printHello 是一个 function 类型,事实上js中函数也是一个变量类型,并且也是一个对象。
箭头函数
箭头函数是es6推出的一个新的语法,箭头函数表达式的语法比函数表达式更简洁。
箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
语法:
([参数1, 参数2, ...]) => 代码块
其中:
上面三个点是表示省略号,表示参数可以有多个。
示例1,声明一个箭头函数,返回1个随机数:
let randNum = () => {
return Math.random();
}
调用方法并打印返回值:
console.log(randNum());
示例2,声明一个箭头函数,传入两个参数,返回和。
let sum = (a, b) => {
return a + b;
};
调用方法并打印返回值:
console.log(sum(1, 2)); // 3
构造器函数
在js可以使用new Function声明函数。
语法结构:
new Function('x', 'y', 'return x * y;');
其中:
前面若干个是函数的参数,最后一个是代码块。
示例1,声明一个函数,传入三个数字,然后求积。
let f = new Function('x', 'y', 'z', 'return x * y * z;');
调用这个函数:
console.log(f(1, 2, 3)); // 6
通过这边我们可以发现,函数居然可以new出来,那么函数难道也是一个对象?
是的,函数也是一个对象,后面我们在讲解原型链的时候,会再提这个话题。
arguments 变量
每一个函数都有一个 arguments 对象,它包括了函数所有的参数,是一个数组对象。
简单示例:
function f(a, b) {
// 打印 arguments 对象
console.log(arguments);
// 打印 arguments 的类型
console.log("arguments类型是:" + typeof arguments);
// 打印 参数 个数
console.log("传递了几个参数:" + arguments.length);
// 遍历打印参数
for (let i in arguments) {
console.log("第" + i + "个参数是:" + arguments[i]);
}
}
调用函数,并传递两个参数:
f(1, 2)
这个正常的调用,控制台打印结果如下:
Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
arguments类型是:object
传递了几个参数:2
第0个参数是:1
第1个参数是:2
当然js中调用函数,不一定要按照他声明的参数个数,可以是1个,也可以是2个、3个等等,如:
f(1)
f(1, 2, 3)
其中 f(1, 2, 3) 控制台打印结果如下:
Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
arguments类型是:object
传递了几个参数:3
第0个参数是:1
第1个参数是:2
第2个参数是:3
怎么样,是不是又惊呆了!原来js还可以这么玩。
示例1,声明一个函数,传入的参数不定,计算所有传入的参数的和,并返回。
因为参数不定,所以我们需要通过 arguments 获取。
function f() {
let sum = 0;
for(let i in arguments) {
sum += arguments[i];
}
return sum;
}
不定参数
因为 arguments 的使用过于隐秘,至少你在调用函数的时候,无法直观的看出需要几个参数,所以es6推出了不定参数的写法。
语法结构:
function 函数名(...参数名) {
代码块
return 返回值
}
其中:
三个点不是表示省略号,是不定参数的语法。
简单示例:
function f(...args) {
// 打印 args 对象
console.log(args);
// 打印 args 的类型
console.log("args类型是:" + typeof args);
// 打印 参数 个数
console.log("传递了几个参数:" + args.length);
// 遍历打印参数
for (let i in args) {
console.log("第" + i + "个参数是:" + args[i]);
}
}
调用函数:
f(1, 2, 3)
控制台打印结果如下:
(3) [1, 2, 3]
args类型是:object
传递了几个参数:3
第0个参数是:1
第1个参数是:2
第2个参数是:3
我们可以发现,这个args货真价实是一个数组了。
因为这种定义不定参数的方式是显式的,所以一般推荐都用这种方式。
系统函数
上面我们可以通过定义函数的语法,定义自己需要的函数,当然js语言也内置了非常多的函数,可以供调用。
如之前学习过的 alert、confirm、prompt 等函数,还有 parseInt、parseFloat、IsNaN、setTimeout、setInterval 等等。
其实这些函数都是 window 对象下的方法,后面讲解 bom 对象是会再进行详细说明。
本节总结
- js中函数定义有4种方式:常规函数、匿名函数、箭头函数、构造器函数。
- js函数的参数可以是不确定的,推荐使用显式的 …args 声明。
- js内置了非常多的系统函数,可以直接调用。
练习题
- 为什么要使用函数?
- js中函数有几种声明方式?
- 定义一个计算圆面积的函数areaOfCircle(),它有两个参数:r: 表示圆的半径;pi: 表示π的值,如果不传,则默认3.14。
- 声明一个匿名函数,传入1个数字,求绝对值。
- 声明一个不定参数的函数,计算所有传入参数的和。
- 声明一个函数,输入一个整数n, 返回 1!+2!+3!+4!+…n!,另外再使用1个函数封装n!。
- 求出所有的水仙花数,使用函数封装判断一个数是否是水仙花数。
- call和apply的区别和作用。