单行从ES 6中的对象获取一些属性

kir*_*oid 145 javascript destructuring ecmascript-harmony ecmascript-6 ecmascript-next

如何编写一个函数,在ES6中以最紧凑的方式只占用少量属性?

我已经提出了使用解构+简化对象文字的解决方案,但我不喜欢在代码中重复的字段列表.

有更薄的解决方案吗?

(v) => {
    let { id, title } = v;
    return { id, title };
}
Run Code Online (Sandbox Code Playgroud)

小智 115

虽然它不会避免重复字段列表,但这里有些更纤细.它使用"参数解构"来避免对v参数的需要.

({id, title}) => ({id, title})
Run Code Online (Sandbox Code Playgroud)

@ EthanBrown的解决方案更为通用.这是一个更惯用的版本,它使用Object.assign和计算属性([p]部分):

function pick(o, ...props) {
    return Object.assign({}, ...props.map(prop => ({[prop]: o[prop]})));
}
Run Code Online (Sandbox Code Playgroud)

如果我们想要保留属性的属性,比如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)})))
    );
}
Run Code Online (Sandbox Code Playgroud)

  • +1很好的答案,torazaburo; 谢谢你让我意识到`Object.assign`; es6就像一棵圣诞树,下面有很多礼物,我几个月后仍然会找到礼物 (9认同)

Eth*_*own 42

我认为没有办法让它比你的答案(或者torazburo)更紧凑,但基本上你要做的就是模仿Underscore的pick操作.在ES6中重新实现它很容易:

function pick(o, ...fields) {
    return fields.reduce((a, x) => {
        if(o.hasOwnProperty(x)) a[x] = o[x];
        return a;
    }, {});
}
Run Code Online (Sandbox Code Playgroud)

然后你有一个方便的可重用功能:

var stuff = { name: 'Thing', color: 'blue', age: 17 };
var picked = pick(stuff, 'name', 'age');
Run Code Online (Sandbox Code Playgroud)

  • (耸肩)我觉得这是你的解决方案的答案; 没有更简洁的_general_解决方案(torazaburo的解决方案从额外的verbage中移除,但基本问题 - 所有属性名称必须写入两次 - 意味着它不会比您的解决方案更好地扩展).我的解决方案至少可以很好地扩展...对于`pick`函数一次,你可以选择你想要的多个属性,它不会加倍. (6认同)

Bra*_*mus 19

解决这个问题的技巧是翻转所采用的方法:不是从原始对象开始,而是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"}
Run Code Online (Sandbox Code Playgroud)


she*_*sek 11

使用逗号运算符的简短解决方案:

const pick = (O, ...K) => K.reduce((o, k) => (o[k]=O[k], o), {})
Run Code Online (Sandbox Code Playgroud)


alx*_*ndr 8

TC39的对象休息/传播属性提议将使这个非常光滑:

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
z; // { a: 3, b: 4 }
Run Code Online (Sandbox Code Playgroud)

(它有创造的缺点xy变量,你可能不需要.)

  • 这是`省略'的一种方便形式,但不是`pick` (33认同)
  • 我希望看到一个与ES提案完全相反的变体:`let {a,b} as z = {x:1,y:2,a:3,b:4}` (5认同)

Sak*_*ham 6

您可以使用对象解构从现有对象中解压属性,并将它们分配给具有不同名称的变量- 最初为空的新对象的字段。

const person = {
  fname: 'tom',
  lname: 'jerry',
  aage: 100,
}

let newPerson = {};

({fname: newPerson.fname, lname: newPerson.lname} = person);

console.log(newPerson);
Run Code Online (Sandbox Code Playgroud)


Est*_*ask 5

ES6 是编写问题时的最新规范。正如在这个答案中所解释的,ES2019 中的关键选择明显短于 ES6:

Object.fromEntries(
  Object.entries(obj)
  .filter(([key]) => ['foo', 'bar'].includes(key))
)
Run Code Online (Sandbox Code Playgroud)