Like what Lodash has implemented _.pick, _.omit:
({a : 1, b : 2}).pick(['a']); // => {a : 1}
({a : 1, b : 2}).omit(['b']); // => {b : 1}
({a : 1, b : 2}).pick(['c']); // => {}
({a : 1, b : 2}).omit(['c']); // => {a : 1, b : 2}
Like what Lodash has implemented _.pick, _.omit:
({a : 1, b : 2}).pick(['a']); // => {a : 1}
({a : 1, b : 2}).omit(['b']); // => {b : 1}
({a : 1, b : 2}).pick(['c']); // => {}
({a : 1, b : 2}).omit(['c']); // => {a : 1, b : 2}
Just a note that an omit I can sort of be done today:
const { a, ...foo } = { a: 1, b: 2 }; // => foo becomes {b : 1}
The pick one is trickier, agree that it would be very nice to have easy such methods.
pick would be Object.fromEntries(keys.map(k => [k, obj[k]]))
, which indeed isn't very ergonomic.
Another problem is whether should we concern about properties from the prototype chain?
const pick = keys => Object.fromEntries(
keys.map(k => obj.hasOwnProperty(k) && [k, obj[k]]).filter(x => x)
);
const omit = keys => Object.fromEntries(
keys.map(k => !obj.hasOwnProperty(k) && [k, obj[k]]).filter(x => x)
);
I have created a draft proposal, and feel free to discuss it.
Yes, a bultin function should do that. And concerning prototypes, Object.prototype.pick
is out of the question, Object.pick
it would need to be.
Btw, with the shorthand improvements proposal you can write const o2 = { o1.a }
, which I'd prefer over o2 = Object.pick(o1, ['a'])
for non-dynamic properties.
Sometimes, if we want to ensure that an object won't has any other side-effected properties, the pick / omit method should be better.
postData({[key1] : o[key1], [key2] : o[key2]});
postData(o.pick([key1, key2]));
Is it triggered the getter or copy the property descriptor?
I disagree, Please do not define in Object.prototype
({ pick: undefined }).pick(['pick'])
({ omit: undefined }).omit(['omit'])
Object.keys({}) // returns ["pick", "omit"]
is this expectation?
You may misunderstand:
Object.keys({ pick: undefined, omit: undefined }); // => ["pick", "omit"]
Object.keys(({ pick: undefined, omit: undefined }).pick(['pick'])); // => ["pick"]
I think this is normal
This can't work, break the web.
({ pick() { throw new Error("pick") } }).pick(["pick"])
In that case, pick must be a method on arrays, otherwise it wouldn’t work (because the keys of that array are 0 and 1).
The second line has mismatched parenthesis, did you mean Object.keys(({…}).pick(…))
or Object.keys({…}).pick(…)
? But neither of them will work with Object.prototype.pick
.
I don't understand why it breaks? For instance:
const pick = (obj, keys) => Object.fromEntries(
keys.map(k => obj.hasOwnProperty(k) && [k, obj[k]]).filter(x => x)
);
pick({
pick() { throw new Error("pick") },
omit: undefined,
}, ['pick']); // => {pick: f}
I have testd the implementation of Lodash, and it of course trigger the getter:
_.pick(Object.defineProperty({}, 'a', {
get: () => 'b',
}), ['a']).a; // => "b"
For arrays:
[1, 2, 3].pick([0]); // => {0: 1}
[1, 2, 3].pick([0, 1]); // => {0: 1, 1: 2}
I DISAGREE, Re-define any object prototype!
I think such a method will only create a new object with copying some of its prototype without redefine them.
You defined in Object.prototype.pick
, thanks.
const foo = { pick() { throw new Error("pick") } }
foo.pick() // here expect is throw a error, but not is `Object.prototype.pick`.