
ES 提案:Object.fromEntries()
提案 “Object.fromEntries” (由 Darien Maillet Valentine, Jordan Harband 和 Kevin Gibbons 提出)处在 stage 4 阶段,因此是 ES2019 的一部分。这篇博客解释它是如何工作的。
Object.fromEntries() 与 Object.entries()
通过可迭代的 [key, value] 部分,Object.fromEntries()
创建一个对象:
Object.fromEntries([
['foo', 1],
['bar', 2],
]);
// {foo: 1, bar: 2}
它是 Object.entries()
的反面:
const obj = {
foo: 1,
bar: 2,
};
Object.entries(obj);
// [['foo',1], ['bar',2]]
结合 Object.entries()
和 Object.fromEntries()
帮助实施对象相关的各种操作,继续阅读示例。
例子
_.pick(object, ...keys)
pick() 删除 object
中不包含 key
的所有属性。删除是非破坏性的:pick()
返回新的副本而没有破坏原对象。举例来说:
const address = {
street: 'Evergreen Terrace',
number: '742',
city: 'Springfield',
state: 'NT',
zip: '49007',
};
pick(address, 'street', 'number');
// {
// street: 'Evergreen Terrace',
// number: '742',
// }
我们可以按照以下实现 pick()
:
function pick(object, ...keys) {
const filteredEntries = Object.entries(object).filter(([key, _value]) =>
keys.includes(key),
);
return Object.fromEntries(filteredEntries);
}
_.invert(object)
invert() 非破坏性的交换 object
的键和值:
invert({ a: 1, b: 2, c: 3 });
// {1: 'a', 2: 'b', 3: 'c'}
我们可以像这样实现它:
function invert(object) {
const mappedEntries = Object.entries(object).map(([key, value]) => [
value,
key,
]);
return Object.fromEntries(mappedEntries);
}
_.mapObject(object, iteratee, context?)
mapObject() 就像 Array
的方法 .map()
,但是作用于对象:
mapObject({ x: 7, y: 4 }, (value) => value * 2);
// {x: 14, y: 8}
这是一种实现:
function mapObject(object, callback, thisValue) {
const mappedEntries = Object.entries(object).map(([key, value]) => {
const mappedValue = callback.call(thisValue, value, key, object);
return [key, mappedValue];
});
return Object.fromEntries(mappedEntries);
}
_.findKey(object, predicate, context?)
findKey() 返回其第一个属性的键 predicate
返回 true
:
const address = {
street: 'Evergreen Terrace',
number: '742',
city: 'Springfield',
state: 'NT',
zip: '49007',
};
findKey(address, (value, _key) => value === 'NT');
// 'state'
我们可以按照以下实现它:
function findKey(object, callback, thisValue) {
for (const [key, value] of Object.entries(object)) {
if (callback.call(thisValue, value, key, object)) {
return key;
}
}
return undefined;
}
实现
Object.fromEntries()
可以按照下面代码实现(忽略了一些检查):
function fromEntries(iterable) {
const result = {};
for (const [key, value] of iterable) {
let coercedKey;
if (typeof key === 'string' || typeof key === 'symbol') {
coercedKey = key;
} else {
coercedKey = String(key);
}
Object.defineProperty(result, coercedKey, {
value,
writable: true,
enumerable: true,
configurable: true,
});
}
return result;
}
通过 npm 包 Object.fromEntries 可获得一个官方的填充。
更多关于 Object.fromEntries 的详情
- 重复键:如果你提供相同的键多次,最后面的键将覆盖前面:
Object.fromEntries([ ['a', 1], ['a', 2], ]); // { a: 2 }
Symbol
键:即使Object.entries()
忽略Symbol
最为键的属性,Object.fromEntries()
依然接受Symbol
作为键。- 键的强制转换:[key, value] 部分的键被强制转化为属性键:字符串和
symbol
类型以外的值被强制转化为字符串。 - Iterables 与 Arrays:
Object.entries()
返回一个数组(与Object.keys()
一致),它是以 [key,value] 组成的二维数组。Object.fromEntries()
是灵活的:它接受iterables
(包括 Arrays 并且与之一致new Map()
)。它的 [key,value] 对只需要是具有键 '0' 和 '1'(包括二维数组)属性的对象。
- 仅支持可枚举的数据属性:如果要创建不可枚举的属性和/或非数据属性,则需要使用 Object.defineProperty() 或 Object.defineProperties()。
译者注:
关于迭代器 Iterables,详见 MDN 的解释。
本文作者 Axel Rauschmayer,转载请注明来源链接: