javascript函数怎样定义_参数传递有什么特点【教程】

JavaScript函数定义有三种:函数声明(提升)、函数表达式(不提升)、箭头函数(不绑定this);参数均为值传递,原始类型传副本,对象类型传地址副本;推荐用剩余参数...args处理不定参;默认参数和解构默认值需注意暂时性死区与null陷阱。

JavaScript 函数定义有哪几种写法?

最常用的是函数声明和函数表达式,箭头函数则适用于特定场景。函数声明会提升(hoist),而函数表达式和箭头函数不会。

常见写法对比:

  • function foo(a, b) { return a + b; } —— 函数声明,可提前调用
  • const bar = function(a, b) { return a + b; }; —— 函数表达式,必须先声明后调用
  • const baz = (a, b) => a + b; —— 箭头函数,不绑定 this,不能用作构造函数

注意:function 关键字开头的是声明;等号右边带 function=> 的是表达式。混淆这两者容易导致 ReferenceErrorTypeError

参数传递是值传递还是引用传递?

JavaScript 统一按「值传递」处理,但值的类型决定了行为表现——原始类型传的是副本,对象类型传的是指向堆内存地址的副本。

这意味着:

  • 修改 numberstringboolean 等原始类型参数,不影响外部变量
  • 修改 obj.proparr.push() 会影响外部对象,因为地址没变
  • 但给参数重新赋值(如 obj = {})不会影响外部变量,因为只是改了本地地址副本

示例:function mutate(o) { o.x = 1; o = {y: 2}; }

,调用后原对象有 x 属性,但不会被替换成新对象。

如何处理不确定数量的参数?

推荐用剩余参数(...args)替代老旧的 arguments 对象,它真正是个数组,支持 mapreduce 等方法。

关键区别:

  • function f(...args) { console.log(args instanceof Array); } → 输出 true
  • function f() { console.log(arguments instanceof Array); } → 输出 false(它是类数组)
  • arguments 在箭头函数中不可用;...args 可以在任何函数中使用

注意:剩余参数必须是最后一个形参,且不能重复出现;解构时也支持类似语法,比如 const [first, ...rest] = arr

默认参数和参数解构怎么安全使用?

默认参数在调用时才求值,支持表达式甚至函数调用;解构赋值默认值则只在对应属性为 undefined 时生效,null 不触发。

典型陷阱:

  • function f(x = y) { let y = 1; } → 报错,y 未定义(暂时性死区)
  • function g({a = 0} = {}) { return a; } → 安全,空对象作为默认实参兜底
  • g(null) 会报错,因为 null 无法解构;应写成 function g(opts = {}) { const {a = 0} = opts; }

复杂参数建议统一用单个配置对象加解构,默认值集中管理,比一堆零散参数更易维护和扩展。