React MUI中return语句后双括号的作用是什么?
(0, fn)(...)写法的疑问与解答 问题背景
我并非JavaScript/前端开发者,目前正在研究React.js的UI库Material-UI(MUI),并发现了一个陌生写法,相关代码如下:
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(TextFieldRoot, (0, _extends2.default)({ className: (0, _clsx.default)(classes.root, className), disabled: disabled, error: error, fullWidth: fullWidth, ref: ref, required: required, color: color, variant: variant, ownerState: ownerState }, other, { children: [label != null && label !== '' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_InputLabel.default, (0, _extends2.default)({ htmlFor: id, id: inputLabelId }, InputLabelProps, { children: label })), select ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Select.default, (0, _extends2.default)({ "aria-describedby": helperTextId, id: id, labelId: inputLabelId, value: value, input: InputElement }, SelectProps, { children: children })) : InputElement, helperText && /*#__PURE__*/(0, _jsxRuntime.jsx)(_FormHelperText.default, (0, _extends2.default)({ id: helperTextId }, FormHelperTextProps, { children: helperText }))] })); });
我已知晓双括号可用于调用另一个函数返回的函数,但本次场景不同,且该写法在MUI中频繁出现,想了解其具体用途。
解答
这种(0, 函数名)(参数)的写法是JavaScript里逗号运算符+函数调用的组合,核心作用和MUI中频繁使用的原因如下:
强制函数在无绑定上下文的环境执行
ES模块中,导出的函数默认会和模块对象绑定,直接调用_jsxRuntime.jsxs()时,函数内部的this会指向模块导出对象。而用(0, _jsxRuntime.jsxs)(...)时,逗号运算符会先计算0(仅作为占位符,无实际意义),再返回函数的独立引用,此时调用该引用时,this会变成全局对象(严格模式下为undefined)——React的工具函数(比如jsxRuntime里的方法)设计时就要求this不能绑定到模块对象,这样写能保证函数执行符合预期。配合打包工具做Tree Shaking优化
代码里的/*#__PURE__*/注释是给Webpack、Rollup这类打包工具的标记,说明这段函数调用是纯函数调用,没有副作用。(0, fn)(...)的写法能让打包工具更清晰地识别出这是独立的纯调用,从而更高效地做Tree Shaking,把未被使用的代码从最终产物中移除,减小打包文件体积。MUI自动生成该写法的原因
MUI的组件源码基于TypeScript编写,编译成JavaScript时(通常用Babel),编译器会自动生成这种写法,一方面是为了兼容不同模块系统的上下文差异,另一方面是最大化优化打包体积,符合现代前端工程的性能要求。
内容的提问来源于stack exchange,提问作者ITS Razex

