# Object.{pick,omit}

**URL:** <https://es.discourse.group/t/object-pick-omit/515>\
**Category:** 💡 Ideas\
**Created:** [October 26, 2020, 8:42am UTC](https://es.discourse.group/t/object-pick-omit/515 "2020-10-26T08:42:46Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [June 12, 2021, 3:44am UTC](https://es.discourse.group/t/object-pick-omit/515/62 "2021-06-12T03:44:18Z")

</div>

You are correct. It would just be a shortcut of that, but without having to introduce a bunch of local variables into the current scope (yes, there's other ways of doing this shortcut, but they all have little downsides).

Though, if we introduce both a pick syntax and a pick function, your version is just a shortcut for this:

```javascript
// before
const newObj = oldObj.[key1, key2]
// after
const newObj = Object.pick(oldObj, [key1, key2])

```

Even without Object.pick(), there's a slightly verbose shortcut for this too:

```javascript
const newObj = {
  [key1]: oldObj[key1],
  [key2]: oldObj[key2],
}

```

If we're ignoring use cases that have shortcuts, then the only value the `oldObj.[]` syntax brings is for this specific scenario: `oldObj.[...someArray]` - a very narrow use case.

When a certain task is common enough, it can be nice to have a little shortcut. Just like the newer `**` operator is just a shortcut for `Math.pow()`

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [June 12, 2021, 4:07am UTC](https://es.discourse.group/t/object-pick-omit/515/63 "2021-06-12T04:07:07Z")

</div>

```javascript
// pick a, b, and c off
// if b doesn't exist, set it to 2
// rename c to C
const newObj = oldObj.{ a, b = 2, c: C }

```

If `b` doesn't exist, it should not be picked off. It seems like another meaning like "restructuring"?

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [June 12, 2021, 4:12am UTC](https://es.discourse.group/t/object-pick-omit/515/64 "2021-06-12T04:12:38Z")

</div>

Sorry, my comment wasn't very clear. If it was more explicit, it would have said "if b does not exist on oldObj, set b to 2 on newObj`

Does that clear up your concern? Or is that how you were already understanding it?

The idea of supporting renaming and providing default values was just an additional idea to go on top of this pick syntax. It's certainly not a necessary piece, just a nice bonus.

(and yes, and the other thread, I had called it "restructuring syntax", because it gave you the ability to restructure objects in different ways. The primary type of restructuring it supported was being able to pick values off an object. Everything else was just extra nice-to-haves)

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [June 12, 2021, 4:21am UTC](https://es.discourse.group/t/object-pick-omit/515/65 "2021-06-12T04:21:04Z")

</div>

Yes, but it has violated the motivation of the proposal, which hopes to introduce a way to pick off something from an existing object. If hoping it works like restructuring, it may be another new proposal to bring out the idea.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [June 12, 2021, 4:53am UTC](https://es.discourse.group/t/object-pick-omit/515/66 "2021-06-12T04:53:24Z")

</div>

I think there's something that's not getting communicated very clearly here.

- The "rename" addon just lets you rename a value as you're picking it
- The "default value" addon just lets you use a default value if there was nothing available to be picked.

Both of these addons are very much related to picking. They never modify the original object. I just chose to call it restructuring in that proposal, but I could have named the proposal "pick syntax" (I almost did), and it would have been just as meaningful of a name.

But let's ignore the "default assignment" and "renaming" addons for now - those aren't necessary anyways, just nice-to-haves that might not actually happen.

What we're left with is literally just a pick syntax. The exact same as @jamiebuilds proposed, and really not any different than what you're proposing, it just looks a little different, but functions the same.

```javascript
const oldObj = { a: 1, b: 2, c: 3 }

// this
console.log(oldObj.{ a, b }) // { a: 1, b: 2 }

// is the same as this
console.log(oldObj.['a', 'b']) // { a: 1, b: 2 }

// this (if we support dynamic keys)
oldObj.{ [dynamicKey] }

// is the same as this
oldObj.[dynamicKey]

// this (if we support dynamic keys)
oldObj.{ ...keys }

// is the same as this
oldObj.[...keys]

```

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [June 12, 2021, 8:12am UTC](https://es.discourse.group/t/object-pick-omit/515/67 "2021-06-12T08:12:27Z")

</div>

Quick question:

```javascript
let o = { x: undefined };
let n = o.{ x, y };
n.hasOwnProperty('x'); // -> true
n.hasOwnProperty('y'); // -> ???

```

From a `pick` method I would expect `false` — i.e. don't create new keys that weren't on the original, unless I explicitly defaulted them. Notably, it would be different from:

```javascript
let oxy = { x: o.x, y: o.y };

```

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [June 12, 2021, 8:21am UTC](https://es.discourse.group/t/object-pick-omit/515/68 "2021-06-12T08:21:58Z")

</div>

> [@theScottyJam](#):
>
> Just to clarify, are you two (@lightmare and @aleen42) proposing these bracket syntaxes in addition

I was simply pointing out an issue with `o.[comma,separated,list]`, and offered an alternative `o[...[comma,separated,list]]`. I don't like either of those, there's reasonably concise syntax for that already (provided the method exists): `Object.pick(o, [comma,separated,list])` or `Object.pick(o, comma, separated, list)`.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [June 12, 2021, 10:26am UTC](https://es.discourse.group/t/object-pick-omit/515/69 "2021-06-12T10:26:43Z")

</div>

It is a vision around picking and thanks for sharing ideas, @jamiebuilds @theScottyJam @lightmare . I have noted under current proposal: [GitHub - aleen42/proposal-object-pick-or-omit: Introduce `Object.{pick,omit}` for operating properties of objects more conveniently.](https://github.com/aleen42/proposal-object-pick-or-omit#visions)

Welcome to discuss it.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [June 12, 2021, 1:19pm UTC](https://es.discourse.group/t/object-pick-omit/515/70 "2021-06-12T13:19:04Z")

</div>

That's something I haven't thought about much @lightmare, but it's a good question. I think you're right, if a value does not exist on the old object, then it won't be picked and placed on the new object, so `n.hasOwnProperty('y')` should be false.

---

<div class="post-metadata">

**Author:** ![septs](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/septs/32/395_2.png) [@septs](https://es.discourse.group/u/septs)\
**Post date:** [July 1, 2021, 11:53pm UTC](https://es.discourse.group/t/object-pick-omit/515/71 "2021-07-01T23:53:59Z")

</div>

@aleen42

1. error model design  
i want based [GitHub - tc39/proposal-error-cause: TC39 proposal for accumulating errors](https://github.com/tc39/proposal-error-cause) design

2. ` __proto__ ` is deprecated feature.  
plz do not support it, thanks  
see [Object.prototype.\_\_proto\_\_ - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto)

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [July 2, 2021, 12:47am UTC](https://es.discourse.group/t/object-pick-omit/515/72 "2021-07-02T00:47:29Z")

</div>

@septs

For point 1, are you suggesting that, for example, when picking properties off of an object, and a getter is triggered that throws an error, the pick function should instead throw some sort of "Failed to pick" error, with its cause set to the original error?

Point 2 seems like a good idea

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [July 2, 2021, 1:09am UTC](https://es.discourse.group/t/object-pick-omit/515/73 "2021-07-02T01:09:12Z")

</div>

The first point seems like a good suggestion, but it seems that the traces has apparently show why the error is thrown?

```javascript
Uncaught Error
    at Object.get (<anonymous>:2:20)
    at Object.pick (<anonymous>:2:10)
    at <anonymous>:1:8 

```

I agree with the second point, and I will update the proposal document later.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [July 20, 2021, 12:34am UTC](https://es.discourse.group/t/object-pick-omit/515/74 "2021-07-20T00:34:44Z")

</div>

Hang on - ` __proto__ ` is deprecated, but it's also just a simple getter/setter on `Object.prototype`. What does it mean to not support "` __proto__ `"? If we find the string "` __proto__ `" in the list of things we want to pick off of the provided object, we then check to see if `passedInObj. __proto__ ` refers to the getter/setter on `Object.prototype` and if so, throw an error? Why add special logic for ` __proto__ ` and not other deprecated features, like `Object.prototype. __defineGetter__ ()`?

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [July 20, 2021, 1:00am UTC](https://es.discourse.group/t/object-pick-omit/515/75 "2021-07-20T01:00:59Z")

</div>

@septs Like what @theScottyJam has said, it seems that a proposal should not take care of deprecated things, and it should be pure enough to just describe whether the prototype should be picked or not. If it should be, deprecated things should become invalid once they have been removed.

---

<div class="post-metadata">

**Author:** ![DenisTRUFFAUT](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/denistruffaut/32/569_2.png) [@DenisTRUFFAUT](https://es.discourse.group/u/DenisTRUFFAUT)\
**Post date:** [August 7, 2021, 10:53am UTC](https://es.discourse.group/t/object-pick-omit/515/76 "2021-08-07T10:53:01Z")

</div>

@theScottyJam Had the same idea

> [@const b = a.{ id, name, age } - Object Cherry Pick](https://es.discourse.group/t/const-b-a-id-name-age-object-cherry-pick/905):
>
> Initial data: const a = { id: 42, name: 'a', age: 21, score: { c:1, php: 3, js: 5 }, likes: ['X', 'Y'] }; Imagine now you want to only pick { id, name, age }. -- no_entry_sign Traditional: Redundant props and object name const b = { id: a.id, name: a.name, age: a.age }; -- no_entry_sign Two-lines Destructuring: Pollutes namespace with props as variables names const { id, name, age } = a; const b = { id, name, age }; -- no_entry_sign One-line Destructuring: Doesn't work, you get …

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [August 7, 2021, 1:24pm UTC](https://es.discourse.group/t/object-pick-omit/515/77 "2021-08-07T13:24:46Z")

</div>

I've seen multiple people independently come up with this same idea now - it shows that it must be a pretty intuitive idea :)

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 9, 2021, 10:24am UTC](https://es.discourse.group/t/object-pick-omit/515/78 "2021-08-09T10:24:04Z")

</div>

If `Object.pick` takes only own properties, then pick & remove might also be useful:

```javascript
b = Object.pluck(a, 'x', 'y');

```

roughly equiv to:

```javascript
b = Object.pick(a, 'x', 'y');
delete a['x'];
delete a['y'];

```

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [August 9, 2021, 12:01pm UTC](https://es.discourse.group/t/object-pick-omit/515/79 "2021-08-09T12:01:32Z")

</div>

That can be done using the current proposal as follows:

```javascript
b = Object.pick(a, 'x', 'y')
a = Object.omit(a, 'x', 'y')

// alternativly

b = Object.pick(a, 'x', 'y')
a = Object.omit(a, ...Object.keys(b))

```

If we were to add such a method, I would prefer that it acted more like a "partition" and returned two new objects instead of modifying the source object. But I'm happy just doing two separate method calls for this use case.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 9, 2021, 1:21pm UTC](https://es.discourse.group/t/object-pick-omit/515/80 "2021-08-09T13:21:34Z")

</div>

> [@theScottyJam](#):
>
> That can be done using the current proposal as follows:

No it can't, I actually want to pick & remove from the original.  
If I wanted a copy, I'd do `b = Object.pluck(a = { ...a }, 'x', 'y')`

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [August 15, 2021, 4:14am UTC](https://es.discourse.group/t/object-pick-omit/515/81 "2021-08-15T04:14:34Z")

</div>

Within current prooosal, you can:

```javascript
const pluck = (obj, keys) => {
    const picked = Object.pick(obj, keys);
    keys.forEach(key => { delete obj[key] });
    return picked;
};

```

Sorry, @theScottyJam I have edited the example.

[Previous page](https://es.discourse.group/t/object-pick-omit/515.md?page=3)

[Next page](https://es.discourse.group/t/object-pick-omit/515.md?page=5)
