JavaScriptでのDestructuring、RESTパラメーター、およびSpread構文の理解

提供:Dev Guides
移動先:案内検索

著者はCOVID-19救済基金を選択し、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

ECMAScript仕様の2015Edition 以降、配列およびオブジェクトを操作するための多くの新機能がJavaScript言語で利用できるようになりました。 この記事で学習する注目すべきもののいくつかは、 destructuringrest parameters 、およびSpread構文です。 これらの機能は、配列またはオブジェクトのメンバーにアクセスするためのより直接的な方法を提供し、これらのデータ構造をより迅速かつ簡潔に操作できるようにします。

他の多くの言語には、破棄、RESTパラメーター、およびスプレッドに対応する構文がないため、これらの機能には、新しいJavaScript開発者と別の言語からの開発者の両方にとって学習曲線がある可能性があります。 この記事では、オブジェクトと配列を分解する方法、spread演算子を使用してオブジェクトと配列を解凍する方法、および関数呼び出しでRESTパラメーターを使用する方法を学習します。

破壊

Destructuringassignment は、オブジェクトのプロパティまたは配列項目を変数として割り当てることができる構文です。 これにより、これらの構造体のデータを操作するために必要なコード行を大幅に減らすことができます。 破棄には、オブジェクトの破棄と配列の破棄の2つのタイプがあります。

オブジェクトの破壊

オブジェクトの破棄により、オブジェクトのプロパティを値として使用して、新しい変数を作成できます。

この例を考えてみましょう。idtitle、およびdateで音符を表すオブジェクトです。

const note = {
  id: 1,
  title: 'My first note',
  date: '01/01/1970',
}

従来、プロパティごとに新しい変数を作成する場合は、各変数を個別に割り当てる必要があり、多くの繰り返しがあります。

// Create variables from the Object properties
const id = note.id
const title = note.title
const date = note.date

オブジェクトの破棄を使用すると、これをすべて1行で実行できます。 各変数を中括弧{}で囲むことにより、JavaScriptは各プロパティから同じ名前の新しい変数を作成します。

// Destructure properties into variables
const { id, title, date } = note

ここで、 console.log()新しい変数:

console.log(id)
console.log(title)
console.log(date)

元のプロパティ値を出力として取得します。

Output1
My first note
01/01/1970

注:オブジェクトを破棄しても、元のオブジェクトは変更されません。 すべてのエントリをそのままにして、元のnoteを呼び出すこともできます。


オブジェクト分解のデフォルトの割り当ては、オブジェクトプロパティと同じ名前の新しい変数を作成します。 新しい変数にプロパティ名と同じ名前を付けたくない場合は、[:)を使用して新しい変数の名前を変更し、[次のX198X]:

// Assign a custom name to a destructured value
const { id: noteId, title, date } = note

新しい変数noteIdをコンソールに記録します。

console.log(noteId)

次の出力が表示されます。

Output1

ネストされたオブジェクトの値を分解することもできます。 たとえば、noteオブジェクトを更新して、ネストされたauthorオブジェクトを作成します。

const note = {
  id: 1,
  title: 'My first note',
  date: '01/01/1970',
  author: {
    firstName: 'Sherlock',
    lastName: 'Holmes',
  },
}

これで、noteを分解してから、もう一度分解してauthorプロパティから変数を作成できます。

// Destructure nested properties
const {
  id,
  title,
  date,
  author: { firstName, lastName },
} = note

次に、テンプレートリテラルを使用して、新しい変数firstNameおよびlastNameをログに記録します。

console.log(`${firstName} ${lastName}`)

これにより、次の出力が得られます。

OutputSherlock Holmes

この例では、authorオブジェクトのコンテンツにアクセスできますが、authorオブジェクト自体にはアクセスできないことに注意してください。 オブジェクトとそのネストされた値にアクセスするには、それらを個別に宣言する必要があります。

// Access object and nested values
const {
  author,
  author: { firstName, lastName },
} = note

console.log(author)

このコードは、authorオブジェクトを出力します。

Output{firstName: "Sherlock", lastName: "Holmes"}

オブジェクトを破棄することは、作成する必要のあるコードの量を減らすのに役立つだけではありません。 また、関心のあるプロパティへのアクセスをターゲットにすることもできます。

最後に、デストラクチャリングを使用して、プリミティブ値のオブジェクトプロパティにアクセスできます。 たとえば、 String は文字列のグローバルオブジェクトであり、lengthプロパティがあります。

const { length } = 'A string'

これにより、文字列の固有の長さプロパティが検出され、length変数と等しくなります。 lengthをログに記録して、これが機能したかどうかを確認します。

console.log(length)

次の出力が得られます。

Output8

文字列A stringは、lengthプロパティを取得するために、ここで暗黙的にオブジェクトに変換されました。

アレイの破壊

配列の破棄により、配列項目を値として使用して新しい変数を作成できます。 この例を考えてみましょう。日付のさまざまな部分を含む配列です。

const date = ['1970', '12', '01']

JavaScriptの配列はその順序を保持することが保証されているため、この場合、最初のインデックスは常に年になり、2番目は月になります。 これを知っていると、配列内のアイテムから変数を作成できます。

// Create variables from the Array items
const year = date[0]
const month = date[1]
const day = date[2]

ただし、これを手動で行うと、コード内で多くのスペースを占める可能性があります。 配列の破棄を使用すると、次のように、配列から値を順番に解凍して、独自の変数に割り当てることができます。

// Destructure Array values into variables
const [year, month, day] = date

次に、新しい変数をログに記録します。

console.log(year)
console.log(month)
console.log(day)

次の出力が得られます。

Output1970
12
01

破壊構文をコンマの間に空白のままにすると、値をスキップできます。

// Skip the second item in the array
const [year, , day] = date

console.log(year)
console.log(day)

これを実行すると、yearおよびdayの値が得られます。

Output1970
01

ネストされたアレイは、構造を解除することもできます。 まず、ネストされた配列を作成します。

// Create a nested array
const nestedArray = [1, 2, [3, 4], 5]

次に、その配列を分解し、新しい変数をログに記録します。

// Destructure nested items
const [one, two, [three, four], five] = nestedArray

console.log(one, two, three, four, five)

次の出力が表示されます。

Output1 2 3 4 5

関数のパラメーターを非構造化するために、非構造化構文を適用できます。 これをテストするには、 Object.entries()からkeysvaluesを分解します。

まず、noteオブジェクトを宣言します。

const note = {
  id: 1,
  title: 'My first note',
  date: '01/01/1970',
}

このオブジェクトを指定すると、 forEach()メソッドに渡される引数を破棄することで、キーと値のペアを一覧表示できます。

// Using forEach
Object.entries(note).forEach(([key, value]) => {
  console.log(`${key}: ${value}`)
})

または、forループを使用して同じことを実行できます。

// Using a for loop
for (let [key, value] of Object.entries(note)) {
  console.log(`${key}: ${value}`)
}

いずれにせよ、あなたは以下を受け取ります:

Outputid: 1
title: My first note
date: 01/01/1970

オブジェクトの破棄と配列の破棄は、単一の破棄の割り当てに組み合わせることができます。 デフォルトパラメータは、デフォルトの日付を new Date()に設定するこの例に示すように、デストラクチャリングで使用することもできます。

まず、noteオブジェクトを宣言します。

const note = {
  title: 'My first note',
  author: {
    firstName: 'Sherlock',
    lastName: 'Holmes',
  },
  tags: ['personal', 'writing', 'investigations'],
}

次に、オブジェクトを分解し、新しいdate変数をデフォルトのnew Date()で設定します。

const {
  title,
  date = new Date(),
  author: { firstName },
  tags: [personalTag, writingTag],
} = note

console.log(date)

console.log(date)は、次のような出力を提供します。

OutputFri May 08 2020 23:53:49 GMT-0500 (Central Daylight Time)

このセクションに示されているように、非構造化割り当て構文はJavaScriptに多くの柔軟性を追加し、より簡潔なコードを記述できるようにします。 次のセクションでは、spread構文を使用してデータ構造を構成データエントリに拡張する方法を説明します。

広める

Spread 構文(...)は、配列、オブジェクト、および関数呼び出しを操作するためのJavaScriptへのもう1つの便利な追加機能です。 Spreadを使用すると、オブジェクトと反復可能オブジェクト(配列など)を解凍または展開できます。これを使用して、データ構造の浅いコピーを作成し、データ操作を容易にすることができます。

配列で拡散

Spreadを使用すると、配列を使用した一般的なタスクを簡素化できます。 たとえば、2つの配列があり、それらを結合したいとします。

// Create an Array
const tools = ['hammer', 'screwdriver']
const otherTools = ['wrench', 'saw']

元々、 concat()を使用して2つの配列を連結していました。

// Concatenate tools and otherTools together
const allTools = tools.concat(otherTools)

これで、spreadを使用して、配列を新しい配列に解凍することもできます。

// Unpack the tools Array into the allTools Array
const allTools = [...tools, ...otherTools]

console.log(allTools)

これを実行すると、次のようになります。

Output["hammer", "screwdriver", "wrench", "saw"]

これは、不変性の場合に特に役立ちます。 たとえば、オブジェクトの配列にusersが格納されているアプリを使用している場合があります。

// Array of users
const users = [
  { id: 1, name: 'Ben' },
  { id: 2, name: 'Leslie' },
]

pushを使用して、既存のアレイを変更し、新しいユーザーを追加できます。これは、変更可能なオプションです。

// A new user to be added
const newUser = { id: 3, name: 'Ron' }

users.push(newUser)

ただし、これによりuser配列が変更され、保持したい場合があります。

Spreadを使用すると、既存の配列から新しい配列を作成し、最後に新しい項目を追加できます。

const updatedUsers = [...users, newUser]

console.log(users)
console.log(updatedUsers)

これで、新しいアレイupdatedUsersに新しいユーザーが追加されましたが、元のusersアレイは変更されていません。

Output[{id: 1, name: "Ben"}
 {id: 2, name: "Leslie"}]

[{id: 1, name: "Ben"}
 {id: 2, name: "Leslie"}
 {id: 3, name: "Ron"}]

既存のデータを変更する代わりにデータのコピーを作成すると、予期しない変更を防ぐのに役立ちます。 JavaScriptでは、オブジェクトまたは配列を作成して別の変数に割り当てる場合、実際には新しいオブジェクトを作成するのではなく、参照を渡します。

この例では、配列が作成され、別の変数に割り当てられます。

// Create an Array
const originalArray = ['one', 'two', 'three']

// Assign Array to another variable
const secondArray = originalArray

2番目の配列の最後の項目を削除すると、最初の項目が変更されます。

// Remove the last item of the second Array
secondArray.pop()

console.log(originalArray)

これにより、次の出力が得られます。

Output["one", "two"]

Spreadを使用すると、配列またはオブジェクトの浅いコピーを作成できます。つまり、最上位のプロパティは複製されますが、ネストされたオブジェクトは引き続き参照によって渡されます。 単純な配列またはオブジェクトの場合、必要なのは浅いコピーだけです。

同じサンプルコードを記述しても、spreadを使用して配列をコピーすると、元の配列は変更されなくなります。

// Create an Array
const originalArray = ['one', 'two', 'three']

// Use spread to make a shallow copy
const secondArray = [...originalArray]

// Remove the last item of the second Array
secondArray.pop()

console.log(originalArray)

以下がコンソールに記録されます。

Output["one", "two", "three"]

Spreadを使用して、setまたはその他のiterableを配列に変換することもできます。

新しいセットを作成し、それにいくつかのエントリを追加します。

// Create a set
const set = new Set()

set.add('octopus')
set.add('starfish')
set.add('whale')

次に、setでスプレッド演算子を使用して、結果をログに記録します。

// Convert Set to Array
const seaCreatures = [...set]

console.log(seaCreatures)

これにより、次のようになります。

Output["octopus", "starfish", "whale"]

これは、文字列から配列を作成する場合にも役立ちます。

const string = 'hello'

const stringArray = [...string]

console.log(stringArray)

これにより、各文字が配列内のアイテムとして配列されます。

Output["h", "e", "l", "l", "o"]

オブジェクトで広がる

オブジェクトを操作する場合、spreadを使用してオブジェクトをコピーおよび更新できます。

元々、 Object.assign()はオブジェクトのコピーに使用されていました。

// Create an Object and a copied Object with Object.assign()
const originalObject = { enabled: true, darkMode: false }
const secondObject = Object.assign({}, originalObject)

secondObjectoriginalObjectのクローンになります。

これは、スプレッド構文で簡略化されています。オブジェクトを新しいオブジェクトにスプレッドすることで、オブジェクトを浅くコピーできます。

// Create an object and a copied object with spread
const originalObject = { enabled: true, darkMode: false }
const secondObject = { ...originalObject }

console.log(secondObject)

これにより、次のようになります。

Output{enabled: true, darkMode: false}

配列の場合と同様に、これは浅いコピーのみを作成し、ネストされたオブジェクトは引き続き参照によって渡されます。

不変の方法で既存のオブジェクトのプロパティを追加または変更することは、スプレッドによって単純化されます。 この例では、isLoggedInプロパティがuserオブジェクトに追加されています。

const user = {
  id: 3,
  name: 'Ron',
}

const updatedUser = { ...user, isLoggedIn: true }

console.log(updatedUser)

これにより、次のように出力されます。

Output{id: 3, name: "Ron", isLoggedIn: true}

Spreadを介してオブジェクトを更新する際に注意すべき重要な点の1つは、ネストされたオブジェクトも同様に拡散する必要があるということです。 たとえば、userオブジェクトにネストされたorganizationオブジェクトがあるとします。

const user = {
  id: 3,
  name: 'Ron',
  organization: {
    name: 'Parks & Recreation',
    city: 'Pawnee',
  },
}

organizationに新しいアイテムを追加しようとすると、既存のフィールドが上書きされます。

const updatedUser = { ...user, organization: { position: 'Director' } }

console.log(updatedUser)

これにより、次のようになります。

Outputid: 3
name: "Ron"
organization: {position: "Director"}

可変性が問題にならない場合は、フィールドを直接更新できます。

user.organization.position = 'Director'

しかし、不変のソリューションを探しているので、既存のプロパティを保持するために内部オブジェクトを広げることができます。

const updatedUser = {
  ...user,
  organization: {
    ...user.organization,
    position: 'Director',
  },
}

console.log(updatedUser)

これにより、次のようになります。

Outputid: 3
name: "Ron"
organization: {name: "Parks & Recreation", city: "Pawnee", position: "Director"}

関数呼び出しで拡散

Spreadは、関数呼び出しの引数とともに使用することもできます。

例として、次のmultiply関数は、3つのパラメーターを受け取り、それらを乗算します。

// Create a function to multiply three items
function multiply(a, b, c) {
  return a * b * c
}

通常、次のように、関数呼び出しへの引数として3つの値を個別に渡します。

multiply(1, 2, 3)

これにより、次のようになります。

Output6

ただし、関数に渡したいすべての値がすでに配列に存在する場合、spread構文を使用すると、配列内の各項目を引数として使用できます。

const numbers = [1, 2, 3]

multiply(...numbers)

これにより、同じ結果が得られます。

Output6

注:スプレッドがない場合、これはapply()を使用して実行できます。

multiply.apply(null, [1, 2, 3])

これにより、次のようになります。

Output6

Spreadがコードをどのように短縮できるかを理解したので、...構文の別の使用法であるrestパラメーターを見てみましょう。

残りのパラメーター

この記事で学習する最後の機能は、restパラメーター構文です。 構文はspread(...)と同じように見えますが、逆の効果があります。 配列またはオブジェクトを個々の値に解凍する代わりに、残りの構文は不定の数の引数の配列を作成します。

たとえば、関数restTestで、argsを無数の引数で構成される配列にしたい場合、次のようになります。

function restTest(...args) {
  console.log(args)
}

restTest(1, 2, 3, 4, 5, 6)

restTest関数に渡されたすべての引数が、args配列で使用できるようになりました。

Output[1, 2, 3, 4, 5, 6]

Rest構文は、唯一のパラメーターとして、またはリストの最後のパラメーターとして使用できます。 唯一のパラメーターとして使用された場合、すべての引数が収集されますが、リストの最後にある場合は、次の例に示すように、残っているすべての引数が収集されます。

function restTest(one, two, ...args) {
  console.log(one)
  console.log(two)
  console.log(args)
}

restTest(1, 2, 3, 4, 5, 6)

これにより、最初の2つの引数が個別に取得され、残りが配列にグループ化されます。

Output1
2
[3, 4, 5, 6]

古いコードでは、arguments変数を使用して、関数に渡されるすべての引数を収集できました。

function testArguments() {
  console.log(arguments)
}

testArguments('how', 'many', 'arguments')

これにより、次の出力が得られます。

[secondary_label Output]1
Arguments(3) ["how", "many", "arguments"]

ただし、これにはいくつかの欠点があります。 まず、arguments変数は矢印関数では使用できません。

const testArguments = () => {
  console.log(arguments)
}

testArguments('how', 'many', 'arguments')

これにより、エラーが発生します。

OutputUncaught ReferenceError: arguments is not defined

さらに、argumentsは真の配列ではなく、最初に配列に変換せずにmapやfilterなどのメソッドを使用することはできません。 また、restTest(one, two, ...args)の例に示すように、残りの引数だけでなく、渡されたすべての引数を収集します。

残りは、配列を破棄するときにも使用できます。

const [firstTool, ...rest] = ['hammer', 'screwdriver', 'wrench']

console.log(firstTool)
console.log(rest)

これにより、次のようになります。

Outputhammer
["screwdriver", "wrench"]

残りは、オブジェクトを破棄するときにも使用できます。

const { isLoggedIn, ...rest } = { id: 1, name: 'Ben', isLoggedIn: true }

console.log(isLoggedIn)
console.log(rest)

次の出力を提供します。

Outputtrue
{id: 1, name: "Ben"}

このように、REST構文は、不確定な量のアイテムを収集するための効率的な方法を提供します。

結論

この記事では、デストラクチャリング、スプレッド構文、およびRESTパラメーターについて学習しました。 要約すれば:

  • 破棄は、配列アイテムまたはオブジェクトプロパティから変数を作成するために使用されます。
  • Spread構文は、配列、オブジェクト、関数呼び出しなどの反復可能オブジェクトを解凍するために使用されます。
  • Restパラメーター構文は、不定の数の値から配列を作成します。

破棄、RESTパラメーター、およびスプレッド構文は、コードを簡潔かつクリーンに保つのに役立つJavaScriptの便利な機能です。

破壊の実際を確認したい場合は、 Propsを使用してReactコンポーネントをカスタマイズする方法を参照してください。この構文を使用してデータを分解し、カスタムフロントエンドコンポーネントに渡します。 JavaScriptの詳細については、JavaScriptシリーズのコーディング方法に戻ってください。