delete メソッドとかで Array.filter
みたいな感じで、 state の中から特定のプロパティを削除して新しいオブジェクトを返したい。
1. Object.assign() で オブジェクトをコピーして delete
JavaScript の delete
演算子は破壊的なので、 Object.assign()
でオブジェクトをコピーしてから使えばOK。
const Tristar = { leader: '神崎美月', member1: '一ノ瀬かえで', member2: '紫吹蘭', }; const omitProperty = (obj) => (key) => { const clone = Object.assign(obj); delete clone[key]; return clone; } omitProperty(Tristar)('member2'); // => {leader: "神崎美月", member1: "一ノ瀬かえで"}
紫吹蘭ちゃんさん… 。゚(゚´ω`゚)゚。
シンプルにOK
2. 分割代入 ( Destructuring assignment ) で除外する
{ deleteKey, ...newObject } = Object
で特定のプロパティを分離できるので、これを利用できそうです。
分割代入構文は {key: var_name, ...others} = object
のようにすると、分割したプロパティの変数名を指定することが出来ます。
e.g.
const obj = { x:1, y:2, z:3 }; const { x: _, ...data } = obj; console.log(_); // => 1 console.log(x); // => ReferenceError: x is not defined
👇実装
const Tristar = { leader: '神崎美月', member1: '一ノ瀬かえで', member2: '紫吹蘭', }; const omitProperty = (obj) => (key) => { const { [key]: _, ...newObjct} = obj; return newObjct; } omitProperty(Tristar)('member2'); // => {leader: "神崎美月", member1: "一ノ瀬かえで"} // 存在しないプロパティの場合も問題なし omitProperty(Tristar)('member3'); // => {leader: "神崎美月", member1: "一ノ瀬かえで", member2: "紫吹蘭"}
いい感じですが、 _
という未使用の変数が出来てしまうので eslint で no-unused-vars
のアラートが出ちゃったりして、ぐぬぬ…という感じです。
{ key: {}, ...others } = object
で変数を作成せずに特定のプロパティを除外できるっぽい
分割代入で取り出すプロパティの変数指定を {}
や []
にすると変数にならないので、単純にオブジェクトから除外できるようです。
{}
, []
を指定する場合は、存在しないプロパティのキーを指定されるとエラーになるので、デフォルト引数を指定してあげる必要がるようです。
cf. 特定のプロパティを除外した新しいオブジェクトを作る(immutableなdelete) - rikubaのブログ
e.g.
const obj = { x:1, y:2, z:3 }; var { x: {}, ...data } = obj; console.log(data); // => {y: 2, z: 3} var { null: {}, ...data} = obj; // => TypeError: Cannot destructure property 'null' of 'obj' as it is undefined. var { null: {} = {}, ...data} = obj; console.log(data); // => {x: 1, y: 2, z: 3}
色々試してみた所、変数指定は NaN
, undefined
でも可能で、これの場合は存在しないプロパティのキーが指定されてもデフォルト引数なしでもエラーにならないようでした。 ( null
を変数に指定することはSyntaxError
になり出来ませんでした。 )
e.g.
const obj = { x:1, y:2, z:3 }; // 変数指定を null にすることは出来ない var { x: null, ...data} = obj; // => SyntaxError: Invalid destructuring assignment target var { x: NaN, ...data} = obj; console.log(data); // => {y: 2, z: 3} var { null: NaN, ...data} = obj; console.log(data); // => {x: 1, y: 2, z: 3} デフォルト引数不要 var { x: undefined, ...data} = obj; console.log(data); // => {y: 2, z: 3} var { null: undefined, ...data} = obj; console.log(data); // => {x: 1, y: 2, z: 3} デフォルト引数不要
変数を作らないので undefined
にしちゃうのがデフォルト引数も不要なので直感的な用に感じました。
これを利用して分割して必要なデータを返す関数にしてしまえば、シンプルに書くことができそうです。
e.g.
const omitProperty = (obj) => (key) => { // プロパティ分割代入な引数で取って残りを返す関数を作成 const omit = ({ [key]: undefined, ...newObjct}) => { return newObjct }; return omit(obj); }; // 👇即時関数にしてしまえば1行に const omitProperty = (obj) => (key) => { return (({ [key]: undefined, ...newObjct}) => newObjct)(obj); };
👇テスト
const Tristar = { leader: '神崎美月', member1: '一ノ瀬かえで', member2: '紫吹蘭', }; const omitProperty = (obj) => (key) => { return (({ [key]: undefined, ...newObjct}) => newObjct)(obj); }; omitProperty(Tristar)('member2'); // => {leader: "神崎美月", member1: "一ノ瀬かえで"} omitProperty(Tristar)(NaN); // => {leader: "神崎美月", member1: "一ノ瀬かえで", member2: "紫吹蘭"}
A W E S O M E .。.:・'(゚▽゚)’・:.。.
💪₍ ᐢ. ̫ .ᐢ ₎✌️
所感
eslint の no-unused-vars を ignore するしかないかなーって思ってたので、分割代入で変数指定を利用して変数を作成しないようにできる Hack は完全に盲点でした。
[参考]
- 特定のプロパティを除外した新しいオブジェクトを作る(immutableなdelete) - rikubaのブログ
- delete 演算子 - JavaScript | MDN
- Object.assign() - JavaScript | MDN
- 分割代入 - JavaScript | MDN
> Take Me Higher <
 ̄YYYYYYYYY^ ̄