Object pick/omit S1
- 阶段: Stage 1
- 状态: 进行中
- ECMAScript 版本: —
- 同步时间: 2026年8月26日
- English original · 官方仓库
该提案引入静态方法 Object.pick 和 Object.omit,基于键列表或谓词函数方便地选择或排除对象属性,弥补了解构赋值在动态属性或原型属性访问方面的人体工程学不足。API 接受可选的键数组或谓词,以及 thisArg,返回新的普通对象,包括对 Symbol 键和原型属性的处理。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
Object.{pick, omit}
ECMAScript 提案,针对
Object.pick、Object.omit的规范与参考实现。
作者: @Aleen && Hemanth HM
倡导者: @js-choi
动机
让我们考虑几个现实场景,来理解本提案试图解决的问题。
- 在
MouseEvent上,我们只关心'ctrlKey'、'shiftKey'、'altKey'、'metaKey'事件。 - 我们有一个
configObject,需要从中获取['dependencies'、'devDependencies'、'peerDependencies']。 - 我们有一个
optionsBag,并允许其中包含['shell'、'env'、'extendEnv'、'uid'、'gid']。 - 从
req.body中,我们想要提取['name'、'company'、'email'、'password']。 - 通过从
props中提取compareKeys并与prevProps比较,检查组件是否应shouldReload。 - 假设我们有一个
depsObject,需要忽略其中所有@internal/packages。 - 我们有
props,需要从中移除['_csrf'、'_method']。 - 我们需要通过从
({ ...state.models, ...action.update })中移除action.deleted来构造newModelData。 - 当过滤列表由
CLI参数给出时,过滤配置对象。
你看,生活就是关于 挑选(pick)我们想要的,以及 省略(omit)我们不想要的!
如果语言提供了便捷的方法来帮助处理类似场景,生活是否会变得更容易?
有人可能会争论说,我们可以如下实现 pick 和 omit:
上述实现的主要挑战:
- 不符合人体工程学!
- 如果选择解构方式,它对
pick根本不起作用,也无法用于动态值的omit。 - 解构不能像
Object.pick那样克隆新对象。 - 解构不能像
Object.pick那样从原型上挑选属性。 - 解构无法动态
挑选属性,而Object.pick可以。 - 解构无法
省略某些属性,而在没有此提案的情况下只能克隆然后删除。
我们可以在下面的 es.discourse 中阅读更多关于此类用例和挑战的信息:
- Object.{pick,omit}。
- Object restructuring syntax。
- Object Array Pick。
- js-pick-notation。
- slect multiple object values。
考虑到这些,如果我们有 Object.pick 和 Object.omit 静态方法岂不更容易?!
现在让我们讨论一下这种有用方法的 API 是什么?
语法
参数
obj:你想要从中挑选或省略的对象。pickedKeys(可选):你想要从对象中挑选的属性的键。默认值为空数组。omittedKeys(可选):你想要从对象中省略的属性的键。默认值为空数组。predictedFunction(可选):用于预测属性是否应被挑选或省略的函数。默认值为恒等函数:x => x。currentValue:对象中当前处理的值。key:对象中currentValue的键。object:调用pick的对象。
thisArg(可选):在预测函数内部用作this的对象。
返回值
- 返回一个新对象,其中包含从对象中挑选或省略的属性。
用法
愿景
-
在挑选情况下的一种语法糖:
为了扩展本提案的动机,可能有一些语法表示法作为从对象中挑选属性的替代,比如提案 proposal-slice-notation:
关于如何包装挑选键有两个想法:
-
方括号:
-
花括号:
目前,关于是否应该挑选具有默认赋值值的属性存在分歧。
尽管如此,这只是一个简单的愿景,欢迎讨论。
-
常见问题
-
当涉及到对象的原型链时,方法应该挑选还是省略? (答案可能改变)
答:Lodash 的
_.pick和_.omit的实现已考虑了链。为了保持规则,我们可以挑选原型上的属性,但不能省略它们:同样的规则适用于
__proto__,即使它已被弃用,因为提案应足够纯粹,不应指定特殊逻辑来消除弃用属性:在某些观点中,从原型链挑选或省略属性应使方法更具扩展性:
-
返回值的类型是什么?
答:所有这些方法应返回普通对象:
-
如何处理
Symbol?答:
Symbol应仅被视为具有Symbol键的属性,并应遵守上述规则: -
如果对象的某些属性不可访问,比如抛出错误,
Object.pick或Object.omit能否操作这样的对象?答:我建议抛出由
Object.pick或Object.omit包装的错误,但这不是最终选择:错误堆栈将如下所示:
-
与proposal-shorthand-improvements 相比,何时应使用这两种方法?
答:多个属性。假设我们需要确保一个对象没有除
key1和key2之外的任何副作用键: -
为什么不能直接在
Object.prototype上定义?答:由于
Object特别基础,两者都会与其他任何对象的属性冲突。简而言之,如果定义了,任何继承自Object的对象,如果其原型中定义了pick或omit,都会破坏。 -
为什么不定义与 Lodash 中的
pickBy和omitBy对应的过滤方法?答:将方法加倍是不必要的,因为可以将其合并到参数中:
此外,传递的过滤方法可以很容易地以相同的含义反转,这意味着
omitBy可以轻松定义为pickBy的逆操作。
注意:您对本提案有任何建议或想法吗?欢迎通过 issues 进行讨论。