如何编写一个函数,在 ES6 中以最紧凑的方式只需要几个属性?
我想出了使用解构 + 简化对象文字的解决方案,但我不喜欢在代码中重复字段列表。
有更精简的解决方案吗?
(v) => {
let { id, title } = v;
return { id, title };
}
如何编写一个函数,在 ES6 中以最紧凑的方式只需要几个属性?
我想出了使用解构 + 简化对象文字的解决方案,但我不喜欢在代码中重复字段列表。
有更精简的解决方案吗?
(v) => {
let { id, title } = v;
return { id, title };
}
这是更精简的内容,尽管它并不能避免重复字段列表。它使用“参数解构”来避免对v
参数的需要。
({id, title}) => ({id, title})
(请参阅其他答案中的可运行示例)。
@EthanBrown 的解决方案更通用。这是它的一个更惯用的版本,它使用Object.assign
, 和计算属性([p]
部分):
function pick(o, ...props) {
return Object.assign({}, ...props.map(prop => ({[prop]: o[prop]})));
}
如果我们想保留属性的属性,例如configurable
getter 和 setter,同时还要省略不可枚举的属性,那么:
function pick(o, ...props) {
var has = p => o.propertyIsEnumerable(p),
get = p => Object.getOwnPropertyDescriptor(o, p);
return Object.defineProperties({},
Object.assign({}, ...props
.filter(prop => has(prop))
.map(prop => ({prop: get(props)})))
);
}
我认为没有任何方法可以使它比您的答案(或 torazburo 的答案)更紧凑,但基本上您要做的是模拟Underscore 的pick
operation。在 ES6 中重新实现它很容易:
function pick(o, ...fields) {
return fields.reduce((a, x) => {
if(o.hasOwnProperty(x)) a[x] = o[x];
return a;
}, {});
}
然后你有一个方便的可重用功能:
var stuff = { name: 'Thing', color: 'blue', age: 17 };
var picked = pick(stuff, 'name', 'age');
解决这一问题的技巧是将所采用的方法颠倒过来:不是从原始对象开始,而是orig
可以从他们想要提取的键开始。
使用Array#reduce
一个然后可以将每个需要的键存储在作为initialValue
所述函数传入的空对象上。
像这样:
const orig = {
id: 123456789,
name: 'test',
description: '…',
url: 'https://…',
};
const filtered = ['id', 'name'].reduce((result, key) => { result[key] = orig[key]; return result; }, {});
console.log(filtered); // Object {id: 123456789, name: "test"}
或者...
const filtered = ['id', 'name'].reduce((result, key) => ({
...result,
[key]: orig[key]
}), {});
console.log(filtered); // Object {id: 123456789, name: "test"}
使用逗号运算符的一个更短的解决方案:
const pick = (O, ...K) => K.reduce((o, k) => (o[k]=O[k], o), {})
console.log(
pick({ name: 'John', age: 29, height: 198 }, 'name', 'age')
)
TC39 的对象休息/传播属性提案将使这非常巧妙:
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
z; // { a: 3, b: 4 }
(它确实有创建您可能不需要的x
和y
变量的缺点。)