JavaScript函数定义与参数处理详解

作者:异步漫步

时间:2026-10-22

浏览:273

本文详解JavaScript中函数的两种定义方式,深入解析参数传递机制、arguments对象的使用限制,以及ES6 rest参数的优雅替代方案。同时提醒开发者注意return语句在自动分号插入机制下的常见陷阱,并提供函数定义练习。

文章目录

JavaScript函数定义方式

JavaScript中函数的定义方法包括以下几种:


function abs(x) {
 if (x >= 0) {
  return x;
 } else {
  return -x;
 }
}

以abs()函数为例,其定义结构如下:

  • function关键字用于声明函数定义;
  • abs为函数标识名;
  • (x)括号内声明函数参数,多参数间使用逗号分隔;
  • { ... }包裹的代码块为函数体,可包含多条语句或为空。

注意:函数体内执行至return语句时立即结束并返回结果,内部可通过条件判断与循环实现复杂逻辑。

若函数无return语句,执行完毕后仍返回结果,值为undefined。

JavaScript中函数属于对象类型,上述abs()函数实为函数对象,abs变量名指向该对象。

因此,函数的另一种定义方式如下:


var abs = function (x) {
  if (x >= 0) {
    return x;
  } else {
    return -x;
  }
};

此方式中,function (x) { ... }为匿名函数(无名称),但被赋值给变量abs,可通过abs变量调用。

两种定义方式完全等价,注意第二种方式需遵循完整语法,在函数体末尾添加分号以表示赋值语句结束。

函数调用与参数传递

函数调用方法

调用函数时,按顺序传入参数即可:


abs(10); // 返回10
abs(-9); // 返回9

JavaScript允许传入任意数量参数而不影响调用,即使传入参数多于定义参数,函数内部无需使用这些多余参数:


abs(10, 'blablabla'); // 返回10
abs(-9, 'haha', 'hehe', null); // 返回9

若传入参数少于定义数量:


abs(); // 返回NaN

此时abs(x)中的参数x值为undefined,计算结果为NaN。

为避免接收到undefined,可对参数进行校验:


function abs(x) {
  if (typeof x !== 'number') {
    throw 'Not a number';
  }
  if (x >= 0) {
    return x;
  } else {
    return -x;
  }
}

arguments对象的使用

arguments对象

JavaScript提供关键字arguments,仅在函数内部有效,始终指向调用者传入的所有参数。arguments类似Array但非Array实例:


function foo(x) {
  alert(x); // 10
  for (var i=0; i<arguments.length; i++) {
    alert(arguments[i]); // 10, 20, 30
  }
}
foo(10, 20, 30);

利用arguments可获取调用者传入的所有参数。即使函数未定义任何参数,仍可获取参数值:


function abs() {
  if (arguments.length === 0) {
    return 0;
  }
  var x = arguments[0];
  return x >= 0 ? x : -x;
}
abs(); // 0
abs(10); // 10
abs(-9); // 9

实际上arguments常用于判断传入参数个数,常见写法如下:


// foo(a[, b], c)
// 接收2~3个参数,b是可选参数,如果只传2个参数,b默认为null:
function foo(a, b, c) {
  if (arguments.length === 2) {
    // 实际拿到的参数是a和b,c为undefined
    c = b; // 把b赋给c
    b = null; // b变为默认值
  }
  // ...
}

若需将中间参数b设为“可选”,须通过arguments判断,重新调整参数并赋值。

ES6 rest参数详解

rest参数

因JavaScript函数允许接收任意参数,必须使用arguments获取所有参数:


function foo(a, b) {
  var i, rest = [];
  if (arguments.length > 2) {
    for (i = 2; i<arguments.length; i++) {
      rest.push(arguments[i]);
    }
  }
  console.log('a = ' + a);
  console.log('b = ' + b);
  console.log(rest);
}

为获取已定义参数a、b之外的参数,需使用arguments并从索引2开始循环以排除前两个参数,此写法繁琐,旨在获取额外rest参数,是否存在更优方案?

ES6标准引入rest参数,上述函数可改写为:


function foo(a, b, ...rest) {
  console.log('a = ' + a);
  console.log('b = ' + b);
  console.log(rest);
}
foo(1, 2, 3, 4, 5);
// 结果:
// a = 1
// b = 2
// Array [ 3, 4, 5 ]
foo(1);
// 结果:
// a = 1
// b = undefined
// Array []

rest参数必须置于末尾,前缀为...,运行结果显示:传入参数先绑定a、b,多余参数以数组形式赋给变量rest,无需arguments即可获取全部参数。

若传入参数未填满正常定义参数,无需担忧,rest参数将接收空数组(非undefined)。

因rest参数属ES6新标准,需测试浏览器兼容性。请使用rest参数编写sum()函数,接收任意参数并返回其和:

窗体顶端


'use strict';
// 测试:
var i, args = [];
for (i=1; i<=100; i++) {
  args.push(i);
}
if (sum() !== 0) {
  alert('测试失败: sum() = ' + sum());
} else if (sum(1) !== 1) {
  alert('测试失败: sum(1) = ' + sum(1));
} else if (sum(2, 3) !== 5) {
  alert('测试失败: sum(2, 3) = ' + sum(2, 3));
} else if (sum.apply(null, args) !== 5050) {
  alert('测试失败: sum(1, 2, 3, ..., 100) = ' + sum.apply(null, args));
} else {
  alert('测试通过!');
}

return语句与自动分号陷阱

注意return语句的使用

前文提及JavaScript引擎存在行末自动添加分号的机制,这可能导致return语句出现严重问题:


function foo() {
  return { name: 'foo' };
}
foo(); // { name: 'foo' }

若将return语句拆分为两行:


function foo() {
  return
    { name: 'foo' };
}
foo(); // undefined

需警惕,因JavaScript引擎在行末自动添加分号,上述代码实际变为:


function foo() {
  return; // 自动添加了分号,相当于return undefined;
    { name: 'foo' }; // 这行语句已经没法执行到了
}

因此正确的多行写法应为:


function foo() {
  return { // 这里不会自动加分号,因为{表示语句尚未结束
    name: 'foo'
  };
}

函数定义练习

练习题目

定义计算圆面积的函数area_of_circle(),包含两个参数:

r: 表示圆的半径;

pi: 表示π的值,若不传递则默认值为3.14

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章