函数对于任何语言来说都是一个核心概念,通过函数可以封装任意多条语句,并且可以在任何地方任何时候调用执行。
函数语法示例:
// 定义函数
function functionName(arg0, ar1,...,argN){
// TODO
}
...
functionName(1,2); // 通过函数名调用已定义的函数
如上所示,我们通过function
关键字定义一个函数,并且可以给函数一个任意的函数名
,函数名后面是一个参数列表
,最后,用花括号包裹着任意多条代码组成的函数体
,这就是一个基本的函数定义语法。
一般来说,函数定义时参数列表中的参数被称为形参
,函数被调用时括号中传递的参数称为实参
。
我所了解的大多数后端语言中( Java、C++、PHP等),对函数形参和实参的要求是比较严格的,也就是说,调用一个函数时,实参列表中参数的个数、类型必须与函数形参列表一致,否则就会出现语法错误。依据这一特性,我们可以通过给一个同名函数设置不同的函数签名( 不同数量、不同类型的参数)来实现不同的功能,这也叫做函数重载。
下面是一个Java语言函数重载的示例:
class MyClass {
int height;
MyClass() {
System.out.println("无参数构造函数");
height = 4;
}
MyClass(int i) {
System.out.println("房子高度为 " + i + " 米");
height = i;
}
void info() {
System.out.println("房子高度为 " + height + " 米");
}
void info(String s) {
System.out.println(s + ": 房子高度为 " + height + " 米");
}
}
public class MainClass {
public static void main(String[] args) {
MyClass t = new MyClass(3);
t.info();
t.info("重载方法");
//重载构造函数
new MyClass();
}
}
//下面时函数运行结果
房子高度为 3 米
房子高度为 3 米
重载方法: 房子高度为 3 米
无参数构造函数
JavaScript与其他语言有所不同的是,JavaScript中的函数不存在函数签名的特性,也就是说,不在乎形参和实参的个数、类型是否相同。
JavaScript中的参数在内部是通过一个数组来表示的,不管函数被调用时传递的参数个数和参数类型,函数接收到的始终是一个内部数组
,而在函数内部,我们可以通过arguments
对象来访问到这个参数数组。(arguments是一个类似数组的对象,我们可以通过类似数组下标的形式来访问arguments对象中的每个元素)
,
有了arguments
这个对象,函数定义时的形参就不再是必需的,我们可以在函数内部使用arguments对象代替。
function test(){
if(arguments.length === 2){
console.log(arguments[0] + arguments[1]);
}
else{
console.log(arguments.length); // arguments.length属性可以返回内部参数数组有几个元素
}
}
test(1,5); // 6
test("you","fool!"); // you fool!
test(1,2,3); // 3
在函数内部,arguments.length属性可以返回实际传入参数的数量,通过判断这个属性,我们可以在函数内部实现不同的功能,这也算是另一种意义上的函数重载了吧。
在一个函数中,arguments
属性和函数的形参
是可以同时使用的,比如下面这样:
function test(arg1,arg2){
console.log(arg1); // "hello"
console.log(arguments[0]); // "hello"
console.log(arg2); // undefined ,因为函数调用时只传入了一个实参,所有第二个参数默认为undefined
};
test("hello");
通过arguments
对象在函数体中可以对参数重新赋值,但这是一种不太严格的写法,如果开启了严格模式,这种重新赋值的操作会无效,并且可能会导致语法错误:
function test1(a1,a2){
arguments[0] = 4;
console.log(a1);
};
function test2(a1,a2){
"use strict"; // 启用严格模式
arguments[0] = 3; // 无效赋值
arguments[1] = 4; // 无效赋值
console.log(a1);
};
function test3(a1,a2){
arguments[0] = 4;
arguments[1] = 4;
console.log(a1 + a2);
};
test1(1); // 4
test2(1); // 1
test3(1); // NaN
在上面的代码中,test3()
调用后在结果为NaN
,这是因为arguments.length
的值是由实参个数决定的,这里函数调用时只传递了一个实参,所以在test3()
函数体中的arguments[1] = 4;
这一语句是无效的,在这个函数体中,a2
的值仍然是undefined
,所以console.log()
时执行的计算其实是4 + undefined
,undefined在JavaScript中表示“未定义”,将它强制转换成数值会返回NaN,所以undefined + 1也会返回NaN。