如何获取JavaScript类构造函数描述符并仅提取其函数体?
问题:获取类构造函数的函数体而非整个类代码
我正在编写一个基于Express的自定义封装,用于自动生成路由(这是一次学习实践,我知道已有不少同类库)。目前遍历类原型的函数描述符时,能将get方法的descriptor的value转为单个方法的字符串;但获取constructor的descriptor并调用toString()时,返回的是整个类的内容,我只想得到构造函数的函数体,不想额外添加解析逻辑,请问是否有办法实现?
示例控制器代码
const BaseController = require('../src/baseController'); /** * Handle requests for the home page */ class HomeController extends BaseController { /** * @param settings Controller settings * @param vault Injected vault client */ constructor(settings, vault) { super(settings); this.vault = vault; } /** * Serve the landing page * @returns */ async get() { await this.renderAsync({ pageTitle: 'Pechanga Demo' }); } } module.exports = HomeController;
当前情况
获取get方法的结果
// 执行代码 Object.getOwnPropertyDescriptor(controllerType.prototype, 'get').value.toString() // 返回结果 async get() { await this.renderAsync('index', { pageTitle: 'Pechanga Demo' }); }
获取constructor的结果
// 执行代码 Object.getOwnPropertyDescriptor(controllerType.prototype, 'constructor').value.toString() // 返回结果(整个类的内容) class HomeController extends BaseController { constructor(settings, vault) { super(settings); this.vault = vault; } // ... 其他方法 }
期望结果
constructor(settings, vault) { super(settings); this.vault = vault; }
解决方案
没有办法不通过解析就能直接获取到构造函数的函数体,这是由JavaScript的语言特性决定的。
原因:类的prototype.constructor属性指向的是类本身,而非单独的构造函数函数对象。所以调用toString()时,会返回整个类的源代码,而不是构造函数的单独代码。而原型上的普通方法(比如示例中的get)是独立绑定在原型上的函数,所以它们的toString()会返回自身的代码。
如果要得到构造函数的函数体,还是需要对类的字符串进行解析,比如用正则匹配提取:
const classSource = HomeController.toString(); // 匹配构造函数的定义,包括参数和函数体 const constructorRegex = /constructor\s*\([^)]*\)\s*\{([\s\S]*?)\}/; const matchResult = classSource.match(constructorRegex); if (matchResult) { // 拼接出完整的构造函数代码 const constructorCode = `constructor${matchResult[0].slice(10)}`; console.log(constructorCode); }
注:这种正则方式需要考虑一些边界情况,比如构造函数内有嵌套的大括号、注释等,复杂场景下可能需要更完善的解析逻辑,但对于常规的控制器类来说已经足够使用。
内容的提问来源于stack exchange,提问作者Kristian Oye
相关产品推荐
相关产品推荐

