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

如何在JavaScript中无需自定义辅助函数即可将构造函数当作普通函数传入参数?

如何在JavaScript中无需自定义辅助函数即可将构造函数当作普通函数传入参数?

我完全懂你遇到的这个问题——用Lodash FP的组合来简化ANTLR4的链式实例化时,构造函数不能直接丢给compose,因为它需要new来调用,直接传的话就会报那个“不能不用new调用构造函数”的错。

你之前尝试直接传构造函数或者硬写new都不行,其实不用自定义_.construct辅助函数,用JavaScript内置的箭头函数或者Reflect.construct就能解决,而且写法也很简洁:

方法1:用箭头函数包裹构造函数调用

直接在_.compose的数组里,给每个构造函数套一层箭头函数,让它接收上一步的结果并通过new实例化:

// imports...
import _ from "lodash/fp.js";

const parse = _.compose([
  _.invoke("MyQuery"),
  (tokens) => new MyGrammarParser(tokens),
  (lexer) => new antlr4.CommonTokenStream(lexer),
  (chars) => new MyGrammarLexer(chars),
  (input) => new antlr4.InputStream(input),
]);

// 调用测试
const tree = parse("field = 123 AND items in (1,2,3)");

方法2:用Reflect.construct(内置API)

如果你更倾向于用原生API来实例化类,Reflect.construct是专门用来调用构造函数的方法,它和new的效果完全等价,写法如下:

// imports...
import _ from "lodash/fp.js";

const parse = _.compose([
  _.invoke("MyQuery"),
  (tokens) => Reflect.construct(MyGrammarParser, [tokens]),
  (lexer) => Reflect.construct(antlr4.CommonTokenStream, [lexer]),
  (chars) => Reflect.construct(MyGrammarLexer, [chars]),
  (input) => Reflect.construct(antlr4.InputStream, [input]),
]);

为什么之前的写法会报错?

  • 直接传构造函数(比如antlr4.InputStream):Lodash FP会把它当作普通函数直接调用(antlr4.InputStream(input)),但构造函数必须用new,所以触发TypeError。
  • 直接在compose里写new antlr4.InputStream:这行代码会在compose初始化时就执行,而不是调用parse的时候,此时输入参数是undefined,自然会报“无法读取undefined的length属性”的错。

而箭头函数/Reflect.construct的写法,是把“实例化动作”包装成了一个等待接收参数的函数,只有当你调用parse(input)时,每个步骤才会依次执行,正确传递上一步的结果并实例化对应的类。

这样既保留了函数组合的简洁性,又不用额外写辅助函数,完全用原生JS或Lodash FP自带的能力解决了问题~

备注:内容来源于stack exchange,提问作者James Baw

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:28:01