ES6の破壊
構文の分解により、関数パラメーターまたは変数のいずれかを使用して、オブジェクトを分解および再結合できます。
制限は、キーのリストが事前に定義されていることであり、質問が言及するように、それらを文字列としてリストすることはできません。キーが英数字以外の場合、構造化はさらに複雑になりますfoo_bar
。
欠点は、キーのリストを複製する必要があることです。これにより、リストが長い場合に冗長コードが生成されます。この場合、構造化によってオブジェクトリテラル構文が重複するため、リストをそのままコピーして貼り付けることができます。
利点は、ES6にとって自然なパフォーマンスの高いソリューションであることです。
IIFE
let subset = (({ foo, bar }) => ({ foo, bar }))(obj); // dupe ({ foo, bar })
一時変数
let { foo, bar } = obj;
let subset = { foo, bar }; // dupe { foo, bar }
文字列のリスト
選択されたキーの任意のリストは、質問に必要な文字列で構成されます。これにより、事前定義せずに、などのキー名を含む変数を使用できますpick(obj, 'foo', someKey, ...moreKeys)
。
JSエディションごとにワンライナーが短くなります。
ES5
var subset = Object.keys(obj)
.filter(function (key) {
return ['foo', 'bar'].indexOf(key) >= 0;
})
.reduce(function (obj2, key) {
obj2[key] = obj[key];
return obj2;
}, {});
ES6
let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => Object.assign(obj2, { [key]: obj[key] }), {});
またはコンマ演算子を使用して:
let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => (obj2[key] = obj[key], obj2), {});
ES2019
ECMAScript 2017にはがObject.entries
ありArray.prototype.includes
、ECMAScript 2019にはがありますObject.fromEntries
。これらは必要に応じてポリフィルすることができ、タスクを容易にします。
let subset = Object.fromEntries(
Object.entries(obj)
.filter(([key]) => ['foo', 'bar'].includes(key))
)
ワンライナーは、Lodashにpick
似たヘルパー関数としてomit
、またはキーのリストが引数を介して渡されるように書き換えることができます。
let pick = (obj, ...keys) => Object.fromEntries(
Object.entries(obj)
.filter(([key]) => keys.includes(key))
);
let subset = pick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1 }
不足しているキーに関する注意
構造化と従来のLodashのようなpick
関数の主な違いは、構造化にundefined
は、サブセットに値を持つ存在しない選択されたキーが含まれることです。
(({ foo, bar }) => ({ foo, bar }))({ foo: 1 }) // { foo: 1, bar: undefined }
この動作は望ましい場合と望ましくない場合があります。構文を破壊するために変更することはできません。
一方では、pick
代わりに選んだキーのリストを繰り返すことによって行方不明のキーを含むように変更することができます:
let inclusivePick = (obj, ...keys) => Object.fromEntries(
keys.map(key => [key, obj[key]])
);
let subset = inclusivePick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1, bar: undefined }