JavaScript中函数的“形参”不是必须的

函数对于任何语言来说都是一个核心概念,通过函数可以封装任意多条语句,并且可以在任何地方任何时候调用执行。
函数语法示例:

// 定义函数
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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值