如何在JavaScript中为自定义类实现Chai风格的should.be.a.integer链式语法
实现思路
这类无括号链式属性调用的核心是利用JavaScript的访问器属性(Getter),每个中间链式节点(比如should、be、a这类语义衔接属性)返回携带当前实例上下文的对象,访问到最终断言属性(比如integer)时执行对应的校验逻辑即可。
基础版实现
class AnyClass { // 此处以校验实例的value属性为例,可替换为你需要校验的任意目标 constructor(value) { this.value = value } // 链式入口属性 get should() { const self = this // 保存当前实例上下文 return { // 中间链式节点be get be() { return { // 中间链式节点a get a() { return { // 最终断言属性:校验是否为整数 get integer() { if (!Number.isInteger(self.value)) { throw new Error(`Expected ${self.value} to be an integer`) } // 返回当前节点可支持后续继续链式调用 return this }, // 可扩展其他断言属性 get string() { if (typeof self.value !== 'string') { throw new Error(`Expected ${self.value} to be a string`) } return this } } } } } } } }
调用测试
// 合法值无报错 new AnyClass(100).should.be.a.integer // 非法值抛出错误 try { new AnyClass('100').should.be.a.integer } catch (e) { console.log(e.message) // 输出:Expected 100 to be an integer }
通用扩展方案
如果需要大量语义衔接词(比如an、and、is这类无实际逻辑仅做语义优化的词),可以用工厂函数批量生成链式节点,避免重复写嵌套getter:
// 链式节点生成工厂 function createChainNode(context, assertions) { const node = {} // 批量注册语义衔接词,全部返回当前节点本身,支持任意顺序调用 const semanticWords = ['be', 'a', 'an', 'is', 'and', 'that', 'has'] semanticWords.forEach(word => { Object.defineProperty(node, word, { get: () => node }) }) // 注册所有断言属性 Object.entries(assertions).forEach(([assertName, handler]) => { Object.defineProperty(node, assertName, { get: () => { handler.call(context) return node } }) }) return node } // 改造后的AnyClass class AnyClass { constructor(value) { this.value = value } get should() { return createChainNode(this, { integer: function() { if (!Number.isInteger(this.value)) throw new Error(`Expected ${this.value} to be integer`) }, positive: function() { if (this.value <= 0) throw new Error(`Expected ${this.value} to be positive`) }, string: function() { if (typeof this.value !== 'string') throw new Error(`Expected ${this.value} to be string`) } }) } } // 支持灵活的链式写法,语义词顺序不影响效果 new AnyClass(200).should.be.a.positive.integer new AnyClass('hello').should.is.a.string
内容的提问来源于stack exchange,提问作者Ebraheem Ijaz
相关产品推荐
相关产品推荐

