Chain
Chain方法用于为目标数据创建一个链式操作代理。在该代理下,可以链式调用对象/数组本身的方法以及 ramda 库的方法,每次方法调用都会返回新的代理,从而实现连续操作。
语法
javascript
Chain(data)参数
dataObject|Array
需要进行链式操作的目标对象或数组。
返回值
Proxy<Object|Array>返回一个 Proxy 代理。当代理上访问到的方法返回值仍为对象或数组时,会自动重新包装为 Proxy;返回值为基本类型时直接返回该值。
描述
Chain 内部使用 Proxy 拦截 get 操作,按以下优先级查找属性:
- 对象本身属性:若
target[p]不为nil,则使用对象本身的方法或属性。- 若是函数:调用并返回
pack(result)包装结果,调用时this绑定为target。 - 若是普通属性:直接
pack(target[p])包装后返回。
- 若是函数:调用并返回
- ramda 方法:若对象本身没有该属性,但 ramda 上存在同名函数,则使用 ramda 方法。
- 当 ramda 方法参数数 > 1 时,自动以 ramda 占位符
r.__填充前置参数,并将target作为最后一个参数传入(柯里化风格)。 - 当 ramda 方法参数数为 1 时,直接对
target调用。
- 当 ramda 方法参数数 > 1 时,自动以 ramda 占位符
- 回退:若以上都不命中,返回
target[p](通常为undefined)。
pack 函数会判断返回值是否为对象或数组,是则包装为 Proxy,否则原样返回。
注意事项
- 依赖 ramda 库:使用前需确保项目中已安装
ramda,Chain 内部通过import * as r from 'ramda'引入。 - 由于使用 Proxy 对象,不支持 IE 浏览器。
- 通过代理访问属性时,对象本身方法优先于 ramda 方法。若对象自身已有同名方法(如
map、filter、reverse),将优先调用对象自身的方法,而非 ramda 的同名方法。 - ramda 方法采用柯里化风格调用,参数顺序与 ramda 原生保持一致,但
target始终作为最后一个参数自动传入。 - 调用对象本身方法时,
this绑定为target,行为与原方法一致。 pack仅对[object Object]与[object Array]进行代理包装,其他引用类型(如 Date、RegExp)不会被包装。
示例
链式调用数组本身方法
链式调用 ramda 方法
混合使用本身属性、方法与 ramda 方法
浏览器兼容
由于使用 Proxy 对象,不支持 IE 浏览器,详细浏览器兼容性参考MDN Proxy 浏览器兼容性
性能考虑
- 每次
get都会触发代理拦截,存在轻微开销,但不影响单次调用复杂度。 pack仅对对象/数组进行代理包装,基本类型直接返回,避免不必要的 Proxy 创建。- 对于高频调用的紧密循环,建议在 Chain 外部完成循环以减少代理开销;Chain 更适合声明式链式写法。
相关函数
- RW - 高级读写领域代理
- deepConvert - 领域JSON解析
- lazyChange - 惰性赋值代理