在《Javascript权威指南》中这样定义:参数有形参(parameter)和实参(arguments)的区别,形参相当于函数中定义的变量,实参是在运行时的函数调用时传入的参数
说白了就是,形参就是函数声明时的变量,实参是我们调用该函数时传入的具体参数。
// 声明函数add时,a、b就是形参。调用函数add(1,2),1,2就是实参
function add(a, b) {
return a + b;
}
add(1, 2)
实参为原始值。当实参为原始值时,此时形参为实参的拷贝。因此,函数体内形参值的改变并不会影响实参
function test(str) { str = 'chinese'; return str; } const str1 = 'china'; const str2 = test(str1); console.log(str1); // china; console.log(str2); // chinese;实参为引用值。当实参为引用值时,此时形参为实参内存地址的拷贝。因此,函数体内形参值的变化在一定情况下会影响实参
function test(obj) { // 形参obj的值实际上为实参obj的内存引用,及形参和实参同时指向同一个内存地址 obj.name = 'typescript'; // 此时改变的为形参与实参同时指向的那个内存地址中的值 // 所以此时也到值实参的name属性发生了变化 obj = { // 此时对形参obj进行重新赋值,给与了它一个新的内存地址 name: 'react', // 从此之后的形参将于实参完全解绑,两者之间不在存在联系 star: 13000; } obj.star = 20000; // 所以这里仅仅是改变了形参的star属性 return obj; } const obj1 = { name: 'javascript', start: 10000, } const obj2 = test(obj1); console.log(obj1); // {name: 'typescript', star: 10000} console.log(obj2); // {name: 'react', star: 20000}
# 拓展
arguments对象的length属性显示实参的个数,函数的length属性显示形参的个数
Javascript定义了arguments对象,用于在函数内部执行,使用argument.length 可以快速获取函数的的实参个数,使用arguments[n]可以获取实参的值
为了预防用户随意传递参数,可以在函数内部判断形参和实参的个数是否一致
// 判断形参和实参个数是否一致
function add(a, b) {
if(add.length === arguments.length) { // 判断形参个数如果和实参个数不一致,则抛出错误
throw new Error('形参与实参个数不一致,请重新调用函数!');
} else {
return a + b;
}
}
try {
console.log(add(2, 3, 4)); // 尝试调用函数,形参和实参个数不一致,会抛出错误提示
} catch(e) {
console.log(e.message) // 捕获异常信息
}