JavaScript组合函数创建方法时箭头函数返回对象加括号的原因
两个写法的本质差异来自JavaScript箭头函数的语法解析规则,和IIFE没有任何关系:
第一个
barker函数的写法是存在语法歧义的错误写法
箭头函数后直接跟大括号{}时,JS引擎会默认将这对大括号解析为函数体的代码块边界,而不是你想要返回的对象字面量。
代码里的bark: () => console.log(...)会被解析为标签语句(label statement,用于代码块跳转标记,日常开发极少使用),后面定义的箭头函数是一个从未被调用的匿名函数表达式。整个barker函数没有显式写return语句,执行后永远返回undefined,传入Object.assign时相当于传入了空值,自然无法正常工作。
你可以自行验证:执行console.log(barker({name: 'test'}))会直接输出undefined,根本拿不到带bark方法的对象。第二个
barker2的写法是箭头函数返回对象的标准正确写法
箭头后跟的圆括号()的作用是将括号内的内容强制解析为表达式,而非代码块。此时括号内的{bark: () => ...}会被正常识别为对象字面量,函数执行时会直接将这个对象作为返回值返回,传入Object.assign时就能正常合并属性和方法。
补充说明:
barker === barker2返回false是必然结果:首先两个是独立创建的函数,引用地址本身就不同;更何况二者执行逻辑完全不同,一个返回undefined,一个返回目标对象,不可能相等。
你可以根据需求选两种规范写法:
- 简写形式(即barker2的写法,适合仅返回对象、无额外逻辑的场景):
const barker = (state) => ({ bark: () => console.log('Woof, I am ' + state.name) })
- 显式return形式(适合函数内需要写额外逻辑,比如参数校验、属性加工的场景):
const barker = (state) => { // 可插入其他自定义逻辑 return { bark: () => console.log('Woof, I am ' + state.name) } }
内容的提问来源于stack exchange,提问作者caveman418

