如何在JavaScript中实现带数值的方法链式调用?
JS实现
five().plus().five().equals()链式调用效果 实现思路
核心是让链式调用的每一步都返回同一个携带内部状态的对象,所有前序产生的数值、待执行的运算逻辑都存在这个对象的私有属性上,后续方法可以直接读取修改这些状态完成计算。
完整代码实现
// 数字函数工厂,批量生成0-9对应的调用函数 const createNumberMethod = (num) => { return function () { // 每个调用返回的对象存储两个状态:当前累计值、待执行运算 const chainObj = { _current: num, _pendingOperator: null, // 运算方法:仅存储待执行运算,不立刻计算 plus() { this._pendingOperator = (a, b) => a + b return this }, minus() { this._pendingOperator = (a, b) => a - b return this }, multiply() { this._pendingOperator = (a, b) => a * b return this }, divide() { this._pendingOperator = (a, b) => a / b return this }, // 结果输出方法 equals() { return this._current } } // 给链式对象挂载0-9对应的数字方法,处理后续数字输入 const numberMap = [ ['zero', 0], ['one', 1], ['two', 2], ['three', 3], ['four', 4], ['five', 5], ['six', 6], ['seven', 7], ['eight', 8], ['nine', 9] ] numberMap.forEach(([methodName, value]) => { chainObj[methodName] = function() { // 存在待执行运算时,先执行运算再更新当前值 if (this._pendingOperator) { this._current = this._pendingOperator(this._current, value) this._pendingOperator = null } else { // 无待执行运算时直接重置当前值 this._current = value } return this } }) return chainObj } } // 初始化0-9对应的全局函数 const zero = createNumberMethod(0) const one = createNumberMethod(1) const two = createNumberMethod(2) const three = createNumberMethod(3) const four = createNumberMethod(4) const five = createNumberMethod(5) const six = createNumberMethod(6) const seven = createNumberMethod(7) const eight = createNumberMethod(8) const nine = createNumberMethod(9)
调用测试
// 你要求的场景 console.log(five().plus().five().equals()) // 输出10 // 其他拓展场景 console.log(seven().minus().two().equals()) // 输出5 console.log(three().multiply().four().equals()) // 输出12 // 多步连续运算 console.log(two().plus().three().multiply().five().equals()) // 输出25
原理解释
- 链式调用的每一步返回的都是同一个
chainObj对象,前序产生的数值会一直存在_current属性中,后续方法可以直接读取该属性获取前序结果。 - 调用运算方法时不会立刻执行计算,只是把对应的运算逻辑存入
_pendingOperator属性,等待下一个数字输入后再执行计算。 - 调用数字方法时,会先判断是否存在待执行的运算:如果有就用前序的
_current值和本次输入的数字执行运算,更新_current后清空待执行运算;如果没有就直接把_current重置为本次输入的数字。 - 最后调用
equals方法时,直接返回当前存储的_current值即可得到最终结果。
内容的提问来源于stack exchange,提问作者travelingengineer
相关产品推荐
相关产品推荐

