JavaScript中兼顾性能的值委托实现方式选择:用对象还是函数?
值委托实现方案选型对比
首先明确两种方案没有绝对的优劣,要结合你的实际使用场景选择,以下是各维度的实测对比:
性能维度
- 对象实现:几乎零额外开销。本质只是字符串常量的映射,JS引擎对对象属性访问的优化已经做到和直接写字面量差异极小,哪怕是高频调用场景也几乎不会产生性能损耗。
- 函数实现:有可忽略的微小开销。每次调用会产生函数入栈、出栈的消耗,只有在每秒执行十万次以上的热点路径中才能感知到差异,普通业务场景完全不用考虑。
实用性&开发效率维度
对象实现的优劣势
优势:
- 适合批量做别名映射,新增短名只需要在对象里加一行键值对,不需要重复写封装逻辑
- 没有额外封装层,原生方法的所有特性都可以直接沿用
劣势:
- 存在
this绑定隐患:如果把document[z.qs]单独提取出来调用,会因为this指向丢失报错 - 代码可读性差:调用时要多写一层属性访问,不熟悉映射表的开发者很难快速理解短名对应的实际含义
- 无法扩展额外逻辑:只能做纯别名,不能加参数校验、默认值、结果缓存这类自定义逻辑
你给出的示例里还有个小笔误:previuousElementSibling拼写错误,正确拼写是previousElementSibling,要注意避免映射表写错导致的不可预期问题。
// 对象实现示例 var z = { fec: 'firstElementChild', nx: 'nextElementSibling', pr: 'previousElementSibling', cl: 'className', ci: 'clientInformation', qs: 'querySelector', qsa: 'querySelectorAll' } document[z.qs]('h3');
函数实现的优劣势
优势:
- 没有
this绑定问题:内部固定调用目标方法,哪怕单独提取函数也能正常执行 - 可扩展性强:可以很方便的增加自定义逻辑,比如给选择器方法加默认根节点、参数校验、结果缓存等
- 可读性更高:调用方式更简洁,见名知意,不需要额外对照映射表
劣势:
- 批量做别名时重复代码多,每个短名都要单独写一次封装逻辑
// 函数实现示例 function qs(el) { return document.querySelector(el); } qs('p');
选型建议
- 如果你的需求只是纯别名映射,没有额外扩展需求,且对性能要求极高,选对象实现即可
- 如果你需要自定义逻辑,或者更看重代码的可维护性、可读性,直接选函数实现,那点性能损耗换开发效率和更低的维护成本非常划算,99%的业务场景下都不会感知到差异。
内容的提问来源于stack exchange,提问作者Gabriel Queiroz
相关产品推荐
相关产品推荐

