You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS默认参数与解构特殊场景:为何赋值0可正常执行?

关于JavaScript解构参数默认值的困惑解答

咱们一步步拆解你遇到的问题,把背后的逻辑说透:

第一种情况:无参数默认值时调用报错

先看你写的第一个函数:

var b = ({a = 1, b = 1, c = 1}) => a + b + c;

这里箭头函数的参数直接是对象解构模式,意味着调用函数时,JS会尝试把传入的参数(没传参的话就是默认的undefined)当作对象来解构。但undefined不是对象,根本没法读取它的属性,所以调用b()时自然就抛出错误了。

第二种情况:带参数默认值时的奇怪表现

再看第二个函数:

var b = ({a = 1, b = 1, c = 1} = 0) => a + b + c;

这里的= 0是给整个参数变量设置默认值,不是直接给解构的对象赋值。当你调用b()时,因为没传参,参数变量会被赋值为默认值0。接下来要对0做对象解构,这时候JS会执行一个关键操作:ToObject转换——它会把数字、字符串这类原始类型值转换成对应的包装对象,0就变成了Number {[[PrimitiveValue]]: 0}这个对象。

然后解构这个Number对象的a、b、c属性,显然这个对象里压根没有这些属性,所以就会用你定义的解构默认值1,三者相加就是3。

调用b([])时,数组本身就是对象,不需要转换。数组对象同样没有a、b、c属性,所以还是用默认值1,结果自然也是3。

关于是否等价于= {}的疑问

你问这是不是等价于var b = ({a = 1, b = 1, c = 1} = {}) => a + b + c;?

在你的这个场景下,结果确实是一样的——因为空对象{}和0转成的Number对象都没有a、b、c属性,都会触发解构默认值。但从本质上来说,二者不完全等价:

  • 如果解构的是Number对象特有的属性(比如toString),0转成的Number对象自带这个属性,而空对象没有,这时候结果就会不同。
  • 比如你把函数改成({toString = 'default'} = 0) => toString,调用b()会返回Number对象的toString方法,而如果默认值是{},则会返回'default'。

所以在你的例子里结果一致,但底层逻辑和扩展场景下是有区别的。

内容的提问来源于stack exchange,提问作者Shyam Babu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:42:37