次のようにオブジェクトの指定プロパティのみをコピーしたいときがあります。
const input = {
a: "A",
b: "B",
c: "C",
d: "D"
};
let output;
output = {
a: "A",
b: "B"
};
console.log(output); // {a: "A", b: "B"}
※let を使っているのは1ファイルで動作確認したからなので、普通はconst 使ってください。
シャローコピーしてプロパティを削除する方法
output = {...input};
delete output.c;
delete output.d;
console.log(output); // {a: "A", b: "B"}
悪くはなさそうですが、オブジェクト作ってから削除するのもどうかなと思います。
普通のオブジェクト生成
output = {
a: input.a,
b: input.b
};
console.log(output); // {a: "A", b: "B"}
これがごくごく普通で一般的な方法と思います。
が input や a とか b を何度も書くのもちょっと冗長に感じます。
分割代入とオブジェクト省略記法を使った書き方
let { a, b } = input;
output = { a, b };
console.log(output); // {a: "A", b: "B"}
a b を重複して書かなければいけないという問題もあるし、それ以上に a b という一時変数が生成されてしまうという問題があります。
次のように書きたいところだけど、そうすると想定した結果にならずに、output = input と同じになってしまいます。
output = {a,b} = input;
console.log(output); // {a: "A", b: "B", c: "C", d: "D"}
関数を使って分割代入とオブジェクト省略記法を使う
そこでこちらの方法。
a b を重複して書かなければいけないという問題は残ったままだけど、一時変数は外部に影響を与えない。
それなりにきれいな書き方だと思う。
output = (({ a, b }) => ({ a, b }))(input);
console.log(output); // {a: "A", b: "B"}
reduceを使う。
何やっているかわからなくなって可読性が悪そうだけど、このような書き方でも同じ出力を行うことができます。
output = 'a,b'.split(',').reduce((r, k)=>{
r[k] = input[k];
return r;
}, {})
console.log(output); // {a: "A", b: "B"}
こういう場合は、関数化してしまうとよいでしょう。関数化してしまえば内部実装などどうでもよいです。
const copyProp1 = (obj, propNames) => {
return propNames.split(',').reduce((r, k)=>{
r[k] = input[k];
return r;
}, {})
};
output = copyProp1(input, 'a,b');
console.log(output); // {a: "A", b: "B"}
Object.assign と map を使う
オブジェクトをそれぞれ作ってマージするというやり方でも行えます。オブジェクト生成数とマージ処理があるのでなんか遅くて無駄な気もしますが。
output = Object.assign({}, ...'a,b'.split(',').map(k=>({[k]: input[k]})))
console.log(output); // {a: "A", b: "B"}
これも、関数化してしまうと内部が読めなくても問題がないです。
const copyProp2 = (obj, propNames) => (
Object.assign({}, ...propNames.split(',').map(k=>({[k]: obj[k]})))
);
output = copyProp2(input, 'a,b');
console.log(output); // {a: "A", b: "B"}
いろいろ対応したいなら、関数に閉じてしまえばよい。
自作の Parts.js で実装してます。
output = copyProperty(input, 'a,b');
// あるいは
output = copyProperty(input, ['a', 'b']);
主な処理のソースコードはここにあります。単に配列か文字列かで場合分けしている程度なことですが。
partsjs/_copyProperty.js at master · standard-software/partsjs
https://github.com/standard-software/partsjs/blob/master/source/object/_copyProperty.js
いろいろな引数に対応したければ、関数で書いてしまえばいいでしょう。
最後に
即時で書くときに
「関数を使って分割代入とオブジェクト省略記法を使う」のやり方もよいかもだけど
誰にでも読みやすいということを考えると
「普通のオブジェクト生成」のやり方が一番いいかもしれません。
何かの参考になったら、LGTMください。
もっとこんな風なやり方あるよ、とかあったら教えていただけると助かります。