ES5与ES6环境下函数默认参数的实现与陷阱

作者:小括号

时间:2026-10-22

浏览:372

本文详细对比了JavaScript中ES5与ES6环境下处理函数默认参数的不同实现方式。重点解析了ES5中利用逻辑或(||)处理默认值时遇到的0、空字符串等假值陷阱,并提供了使用三元运算符、封装函数及arguments对象的高级技巧。同时介绍了ES6原生默认参数语法的简洁用法,包括必填参数校验和复杂结构解构默认值的处理方案。

文章目录

函数默认参数是提升代码健壮性的重要手段。

根据MDN文档,函数默认参数允许在参数未传入或值为undefined时使用预设的形参值。

ES5环境下的实现

ES5环境下的实现

利用逻辑或运算符(||)

在ES5标准中,语言并未直接提供处理函数默认值的语法特性。因此,开发者通常需要手动增强函数逻辑,常见的做法如下:


function doSomething (name, age) {
 name = name || 'default name'
 age = age || 18
 console.log(name, age)
}

以处理name和age两个参数为例,若未传入值则使用默认值。

执行该函数后,表面看起来运行正常:


doSomething()    // default name, 18
doSomething('Niko') // Niko    , 18
doSomething(, 12)  // default name, 12

然而,当执行以下代码时,会出现不符合预期的结果:


doSomething('Niko', 0) // Niko, 18

可以看出,对于参数0的情况,上述默认参数实现方法存在缺陷。

如下四个表达式的输出均为“wrong”,这显然不符合MDN对函数默认参数的定义:


console.log(0     || 'wrong')
console.log(''    || 'wrong')
console.log(null   || 'wrong')
console.log(false   || 'wrong')

正确的实现方式

因此,在ES5环境中,正确的默认值处理应如下所示:


function doSomething (name, age) {
 if (name === undefined) {
  name = 'default name'
 }
 if (age === undefined) {
  age = 18
 }
 console.log(name, age)
}

利用三元运算符简化操作

或者可以将其简写为三元运算符的形式:


function doSomething (name, age) {
 name = name === undefined ? 'default name' : name
 age = age === undefined ? 18       : age
 console.log(name, age)
}

通过函数进行封装

如果每次编写函数都重复执行这些操作,显然过于繁琐。因此,我们可以对该逻辑进行简单封装:


function defaultValue (val, defaultVal) {
 return val === undefined ? defaultVal : val
}
function doSomething (name, age) {
 name = defaultValue(name, 'default name')
 age = defaultValue(age , 18)
 console.log(name, age)
}

这样即可在ES5中简洁地实现函数默认参数的逻辑。

补充技巧

关于上述defaultValue函数的实现,在合理利用弱类型语言特性的基础上,可以使用以下方式省略三元运算符的操作:


function defaultValue () {
 return arguments[+(arguments[0] === undefined)]
}

我们知道,arguments对象表示函数接收的所有实参。

通过arguments[0]获取第一个实参,并与undefined进行全等比较。

在外层将表达式的结果转换为Number类型,并将该值作为下标从arguments中获取对应的参数。

由于该表达式由Boolean值转换而来,结果仅存在0和1两种情况。

这便实现了与三元运算符相同的功能。

ES6环境下的实现

ES6环境下的实现

ES6版本的函数默认值基本沿用了上述逻辑,但提供了原生语法支持,使得使用更加简洁:

ES6引入了新语法,允许在函数声明参数后直接通过= [defaultValue]的形式设置默认值。


function doSomething (name = 'default name', age = 18) {
 console.log(name, age)
}

ES6中提供了新的语法,可以让我们在函数声明参数后边直接写= [defaultValue]的这种形式来设置某个参数的默认值。 直接使用这种方式,省去了在函数内部进行默认值的检查,能够让函数专注的做它应该做的事情。

如何针对必填参数抛出异常

ES6的新语法使我们能够很好地针对某个必填参数进行错误提示:


function requireParams () {
 throw new Error('required params')
}
function doSomething (name = requireParams(), age = 18) {
 // do something
}

如果name参数为undefined,则会触发默认值规则。

此时调用requireParams函数,该函数直接抛出一个Error对象。

复杂结构参数的默认值处理

上述处理均针对简单的基本类型数据,但如果遇到如下函数:


function init ({id, value}) {}
init({
 id: 'tagId',
 value: 1
})

在ES5环境下,针对此类参数的默认值处理将变得极其复杂。

首先需要判断该参数是否存在,接着需判断参数对象中所有key是否存在。

而在ES6中,可以这样实现:


function init ({
 id  = 'defaultId',
 value = 1
} = {}) {
 console.log(id, value)
}
init()

首先在解构函数后添加默认值= {},然后针对每一项参数添加默认值,从而简洁地实现需求。

ES5版本的polyfill代码位于仓库中的defaultValue目录。

参考资料

1. MDN

总结

以上介绍了在ES5与ES6环境下处理函数默认参数的实现方法,希望对大家有所帮助。如有任何疑问,欢迎留言,小编会及时回复大家!

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章