Skip to content
This page has been auto-translated and may contain errors.View in English

配列

docs.scrimba.com

ショッピングカート、スコアのリスト、グループチャットの全員の名前があるとします。変数1つが値1つを保持するので、このような方法でリストを保存することは、別の名前がたくさん必要になります:price1price2price3など、ループする方法やいくつあるかを確認する方法がありません。配列はそれを解決します。単一の名前の下に順序付けられた値のリストを保持し、独自の長さを知っているので、リストに追加したり、任意の項目を読み取ったり、全体をわずか数行で歩くことができます。

配列を作成して読み取る

**配列**は値の順序付きリストです。角括弧で記述し、値はカンマで区切ります:

js
const prices = [4, 9, 2, 7];

これは1つの変数pricesで、4つの数字を保持しています。単一の値を読み取るには、その位置(インデックスと呼ばれます)を角括弧で使用します。最初はほぼ全員を悩ませるポイント:カウントは1ではなく0から始まります。

js
const names = ["太郎", "花子", "次郎"];
console.log(names[0]); // 太郎
console.log(names[1]); // 花子

配列に何個の項目があるかを確認するには、.lengthを使用します:

js
console.log(names.length); // 3

カウントは0から始まるため、最後の項目はlength - 1に置かれています。lengthではありません。したがって、ここで最後の名前はnames[2]であり、names[3]は終わりを越えます。

配列は1つの名前の下の値の順序付きコレクションです。角括弧リテラルで作成し、0からカウントされたポジションインデックスで任意の項目を読み取ります:

js
const prices = [4, 9, 2, 7];
console.log(prices[0]); // 4
console.log(prices[2]); // 2

0ベースのインデックスは最初の非1個オフバイワンバグの原因なので、今すぐ頭の中で修正する価値があります:最初の項目はインデックス0にあり、最後はlength - 1にあります。

js
console.log(prices.length); // 4
console.log(prices[prices.length - 1]); // 7、最後の項目

存在しないインデックスを読み取ると、エラーはスローされません。prices[10]undefinedを与えます。これはJavaScriptが「ここに何もありません」と言う方法です。その静かな結果は便利であり、時々罠です。インデックスのタイプミスは大きな失敗ではなくundefinedを与えるため、です。

**配列**は0から数えられるインデックスで作成、アクセスされる順序付きコレクションです。項目はインデックスで読み取られ、.lengthがカウントを報告します:

js
const prices = [4, 9, 2, 7];
console.log(prices[0]); // 4
console.log(prices.length); // 4
console.log(prices[prices.length - 1]); // 7、最後の項目

正確に名付ける価値がある2つのプロパティがあります。最初に、.lengthは最初に宣言した固定サイズではありません。使用されている最高のインデックスを追跡し、項目を追加・削除すると更新されます。第2に、範囲外の読み取りは例外をスローするのではなくundefinedを返すため、オフバイワンエラーは後で例外として発生するのではなく、undefinedがロジックを通り抜けます。失敗を大きくしたい場合は、インデックスを自分でlengthに対してガードしてください。

配列は混合値タイプを保持できます([1, "two", true])、が、機能するコードベースはほぼ常に1つの配列を1種類の物に保ちます。配列を読む全てのコードがそれが何であるかを知っているからです。ここでの一貫性は言語規則ではなく、可読性の決定です。

Juno配列を作成して読み取る 配列は1つの名前の下の角括弧内の値のリストです。names[0]でその位置で項目を読み取り、カウントは0から始まるため、最初の項目は[0]であることを覚えてください、[1]ではなく。その0は1週間私を悩ませたので、リストが1つオフの場合は常にチェックしてください。.lengthを使用して項目をカウントし、最後のものはlength - 1に住んでいます。
Juno配列を作成して読み取る 配列は1つの名前の下に順序付きリストを保持し、0からカウントされたインデックスで項目を読み取ります。最後の項目はlength - 1にあります。これはほとんどの初期オフバイワンバグがどこから来ているかです。終わりを過ぎて読み取ると、エラーが発生する代わりにundefinedが返されるため、タイプミスされたインデックスは大きく失敗するのではなく静かになります。値が明らかな理由なくundefinedとして現れるときにそれを念頭に置いてください。
Juno配列を作成して読み取る ブラケットリテラル、0ベースのインデックス、および最高インデックスの使用を追跡するのではなく宣言したサイズを追跡する.length。範囲外の読み取りは例外をスローするのではなくundefinedを返すため、オフバイワンエラーはそれが噛む前に下流で移動します。その失敗を大きくしたい場合は、インデックスを自分でlengthに対してガードしてください。そして1つの配列を1つのタイプのものに保ってください。言語がそれを強制するのではなく、配列の全ての読者がそれが何を保有しているか知っているからです。

配列を変更する

配列は変更を予定して作られています。最も到達する2つは最後に追加または削除します:pushは項目を追加し、popは最後のものを削除します。

js
const cart = ["apples", "bread"];
cart.push("milk");
console.log(cart); // ["apples", "bread", "milk"]
cart.pop();
console.log(cart); // ["apples", "bread"]

マッチングペアは開始で機能します:unshiftは前に追加し、shiftは最初の項目を削除します。

js
cart.unshift("eggs");
console.log(cart); // ["eggs", "apples", "bread"]

インデックスに割り当てることで項目を直接置き換えることもできます:

js
cart[0] = "bananas";
console.log(cart); // ["bananas", "apples", "bread"]

何かを見つけるには、includesははいまたはいいえを教え、indexOfはそれがどこにあるか(またはそこにない場合は-1)を教えます:

js
console.log(cart.includes("apples")); // true
console.log(cart.indexOf("bread")); // 2

初期に知る価値がある1つのこと:const配列は依然として変更できます。 constは名前cartを全新しい配列に再割り当てするのを止めますが、指し示すリストは依然としてpushpop、インデックス割り当てのために開いています。

配列は所定の場所で変更されるように作られています。2つのメソッドペアが最も機能し、各端で1つ:

js
const cart = ["apples", "bread"];
cart.push("milk"); // 最後に追加
cart.pop(); // 最後から削除
cart.unshift("eggs"); // 開始に追加
cart.shift(); // 開始から削除

pushpopは安価で一般的なペアです。それを絶えず到達します。shiftunshiftは前に触れるため、他の全ての項目がスロットを上または下に移動する必要があります。大きな配列では、より多くの作業を行います。順序があなたのものである場合、終わりを好みます。

インデックスに割り当てることで任意の位置を上書きでき、2つの方法で項目を見つけることができます:

js
const names = ["太郎", "花子", "次郎"];
names[1] = "美咲";
console.log(names.indexOf("次郎")); // 2、またはない場合は-1
console.log(names.includes("太郎")); // true

何かが存在しているかどうかのみ気にする場合はincludesに到達し、位置も必要な場合はindexOfに到達します。どちらも===と比較するため、indexOf("2")は数字の2を見つけません。

const配列は依然として完全にミュータブルです:constは名前をロックし、コンテンツではなく。 cartを新しい配列に指すことはできませんが、それが保有する1つにすべての日をpushできます。

配列はミュータブルであり、コア・メソッドは新しい方法を返す代わりに所定の場所で配列を変更します。push/popは端で動作し、shift/unshiftは前で動作します:

js
const cart = ["apples", "bread"];
cart.push("milk"); // 新しい長さを返し、cartをミュータブル化
const removed = cart.pop(); // 削除された項目を返し、cartをミュータブル化

終わりと前は等しいコストではありません。pushpopは単一のスロットに触れます。shiftunshiftは全ての残りの要素を再インデックスします。これは配列の長さに対する線形の作業です。大きな配列を繰り返しshiftする熱いループは静かにそれが見えるより遥かに多くを行っています。順序があなたの管理下にある場合、変更を終わりに保ちます。

インデックスに割り当てるのは所定の場所に書き込み、検索は必要により分割されます:存在のためのincludes、位置のためのindexOf-1は存在しません)。両方とも厳密な平等(===)を使用するため、タイプは重要です:

js
const ids = [1, 2, 3];
console.log(ids.indexOf("2")); // -1、文字列は数字と一致しません
console.log(ids.includes(2)); // true

constポイントは正確に述べる価値があります。参照モデルが最初に表示される場所であるため:constは名前を1つの配列にバインドし、再バインドを禁止しますが、配列のコンテンツについては何も言いません。cart.push(...)は、指し示すオブジェクトをミュータブル化し、cart = [...]とは異なる操作です。その区別は次のセクションの全てのサブジェクトです。

Juno配列を変更するpushpopは最後に追加・削除します。unshiftshiftは同じ開始を行います。cart[0] = "bananas"のようにインデックスに割り当てて項目を置き換え、includesまたはindexOfを使用して見つけます。私を驚かせた部分:const配列は依然として変更でき、constは全新しい配列のために全配列をスワップするのを止めるだけだからです。
Juno配列を変更する 2つのペアがほとんどのエディットをカバーします:最後のpush/pop、開始のshift/unshift。前のペアは他の全ての項目を移動するため、順序がしたがって終わりを好みます。includesは存在をチェックし、indexOfは位置を与え、両方は===と一致するため、"2"は数字の2を見つけません。そしてconstは名前をロックし、コンテンツは決してロックしません。すべての日をconst配列にプッシュできます。
Juno配列を変更する これらのメソッドは所定の場所でミュータブル化します:push/popは1つのスロットに触れ、shift/unshiftは全配列を再インデックスするため、大きな配列をループし続けて移動するループは毎回線形の作業を行っています。includesindexOfはどちらも===を使用するため、文字列インデックスは数字と一致しません。そしてconstはのみ名前の再バインドを禁止します。cart.push() ミュータブル化配列はcart = []とは異なるものです。そのギャップはまさに次に来ている参照の物語です。

配列をループする

リストを取得したら、通常はすべての項目で何かをしたいと思います。配列を読み通す最もクリーンな方法はfor...ofで、一度に1つの項目をあなたに与えます:

js
const prices = [4, 9, 2, 7];
for (const price of prices) {
  console.log(price);
}
// 4
// 9
// 2
// 7

インデックスやカウンターを管理する必要はありません。for...ofはあなたに順序で各値を与え、あなたはそれをどのように名付けるかについて(price)好みのように命名します。すでにループに会った場合、これは配列にとって最も親切なものです。

forEachもあり、各項目に対して小さな関数を1回実行します:

js
const names = ["太郎", "花子", "次郎"];
names.forEach(function (name) {
  console.log("Hi " + name);
});

両方とも全配列を歩きます。読みをクリーンに読みたいときはfor...ofに到達し、配列を変換することを学ぶときはforEachと従兄弟に再び会うでしょう。

配列を読む現代のデフォルトはfor...ofです。管理するインデックスなしでそれぞれの値を直接与え、オフバイワンスリップの可能性もありません:

js
const prices = [4, 9, 2, 7];
let total = 0;
for (const price of prices) {
  total = total + price;
}
console.log(total); // 22

値を順序で希望し、クリーンなコードを希望する場合はfor...ofを使用します。インデックスも必要な場合(例えば、リストに番号を付ける場合)、古典的なカウントforループまたはforEachの2番目の引数がそれを提供します。

forEachはコールバック(あなたが与える関数)を項目ごとに1回実行します:

js
const names = ["太郎", "花子", "次郎"];
names.forEach((name) => {
  console.log("Hi " + name);
});

forEachは副作用のリスト読み取り(ログなど)をよく読みます。それができないことは早期にbreakすることです。途中で停止する必要があるときは、for...ofを使用してください。古い配列から新しい配列を構築することは、独自のツールで別の仕事です。配列メソッドでカバーされています。

単純な読み取りの場合、for...ofは慣用的な選択です:値を直接反復し、インデックス計算をサイドステップし、breakcontinueをサポートします:

js
const prices = [4, 9, 2, 7];
let total = 0;
for (const price of prices) {
  if (price > 8) continue;
  total = total + price;
}
console.log(total); // 13、9をスキップしました

forEachは要素ごとにコールバックを取得し、副作用を読みやすくしますが、標準化する前に知る価値のある2つの制約があります。それはbreakできないため、常に最後まで実行され、返された値を無視するため、結果を生成しようとしているときに間違ったツールです。そのために、変換メソッド(mapfilterreduce)が存在し、配列メソッドはそこに属します。

js
const names = ["太郎", "花子", "次郎"];
names.forEach((name, index) => {
  console.log(index + ": " + name);
});

コールバックの2番目の引数はインデックスで、手動カウンターなしで位置を回復する方法です。経験則:制御フロー必要な場合またはを外部変数に累積している場合はfor...of、1項目の副作用がより明確に読む場合はforEach、変更やログではなく新しい配列を取得したい場合は変換メソッドします。

Juno配列をループするfor...ofは配列を歩く明確な方法です:それはあなたに順序で各項目を与え、あなたは決してインデックスに触れません。forEachは各項目に対して小さな関数を1回実行し、これは便利です。両方は全リストを通り抜けるため、それを直線的に読みたいときにfor...ofを選ぶとします。配列を変換することを学ぶと、より多くの配列ツールが表示されます。
Juno配列をループするfor...ofは配列を読むのに現代的なデフォルトです:値は順序で、管理するインデックスはなく、breakは早期に停止する必要があるときに機能します。forEachは項目ごとにコールバックを実行し、ログのような副作用を読みやすくしますが、breakができないため、常に最後まで実行されます。古い配列から新しい配列を構築することは、独自の方法を持つ別の仕事です。疑わしい場合、for...ofです。
Juno配列をループするfor...ofは値を直接反復し、breakcontinueをサポートするため、制御フロー必要な場合またはを外部変数に累積している場合に優勝します。forEachは1項目の副作用を読みやすくしますが、breakができず、返された値を無視するため、結果を生成するのに間違ったツールです。新しい配列を取得したいときは、ループの代わりに変換メソッドに到達します。その2番目のコールバック引数は、位置が必要な場合はインデックスを提供します。

配列は参照によって保持される

ここは人々を驚かせる動作なので、初期に見る価値があります。配列変数を別の名前にコピーすると、2番目の配列は取得しません。両方の名前が同じものを指しています。

js
const original = [1, 2, 3];
const copy = original;
copy.push(4);
console.log(original); // [1, 2, 3, 4]

copyにプッシュするのはoriginalを変更しました。配列は1つだけだからです。=は2番目の名前に、新しいコピーではなく、同じリストを与えました。これは、配列が参照によって保持されていることを意味するとき、人々が言っていることです:変数はリストそのもので、リストへのポインタを保持します。

実際の、独立したコピーを取得するには、...で配列を新しいものに拡散します:

js
const original = [1, 2, 3];
const copy = [...original];
copy.push(4);
console.log(original); // [1, 2, 3]、触れられない

数字または文字列は値によって保持されます:変数をコピーすると値がコピーされます。配列は異なります。これは参照によって保持されるため、変数をコピーするのはポインタをコピーし、両方の名前が同じ配列を指します。

js
const original = [1, 2, 3];
const shared = original;
shared.push(4);
console.log(original); // [1, 2, 3, 4]、同じ配列

これは前のconst注記の背後にある同じ事実です:配列はオブジェクトであり、変数はそのオブジェクト自体ではなく、そのオブジェクトへの参照を保持します。どちらかの名前を通じてミュータブル化すると、彼らが共有している1つの配列をミュータブル化します。

独立したコピーを希望するときは、新しい配列に拡散します。...は各項目を越えてコピーします:

js
const original = [1, 2, 3];
const copy = [...original];
copy.push(4);
console.log(original); // [1, 2, 3]、独立した

これは浅いコピーです:新しい配列は独自のリストですが、項目が彼ら自身の配列である場合、両方のコピーは依然としてそれらの内部配列を共有します。平野数字と文字列では、浅いはあなたが必要なすべてです。

プリミティブ(数字、文字列、ブール値)は値によって保持されます。配列はオブジェクトであり、参照によって保持されます。「含む」配列である変数は実際にそれへの参照を保持するため、割り当てはその参照をコピーし、その配列を指す全ての名前は全ての変化を見ます:

js
const original = [1, 2, 3];
const alias = original;
alias.push(4);
console.log(original); // [1, 2, 3, 4]
console.log(original === alias); // true、同じ配列

これがconstとミュータビリティが別の懸念である理由です:constは参照を修正し、変化は参照が指しているものを変えます。これはまたイミュータビリティを好む議論です。所定の場所で1つを変更するのではなく、新しい配列を生成します。共有ミュータブルな状態は、受け取った配列をミュータブル化する関数がその参照の全ての他のホルダーのためにそれを静かに変更することを意味し、これはトレースするのが難しいバグのクラスです。新しい配列を返すと、各呼び出し元のデータはその独自のものになります。

スプレッド演算子は浅いコピーを作成します:同じ項目がコピーされた新しい外部配列です。

js
const original = [1, 2, 3];
const copy = [...original];
console.log(copy === original); // false、異なる配列

浅いは重要な言葉です。新しい配列は独立していますが、その内部に配列が入れ子になっている場合は、依然として参照により共有されるため、深い構造はスプレッド以上を必要とします。プリミティブの配列でこれまでにあることはすべて、スプレッドは完全なコピーです。

構造をすべて選択するのに関しては:配列は順序付きリストを持つ場合、位置またはカウントが重要な場合、価格のキュー、名前の配列は正しいツールです。代わりに、位置ではなく有意なキーで値を検索したい場合、それはいわゆるオブジェクトであり、関数はこの配列の作業の多くが終わる場所です。

Juno配列は参照によって保持される=で配列変数をコピーするのは2番目の配列を作成しません。両方の名前が同じものを指します。これは一度以上私を噛んだ。独立したコピーを希望するときは、[...original]で拡散させてください。これはあなたが独立して変更できるフレッシュな配列を構築します。
Juno配列は参照によって保持される 数字と文字列は値によってコピーします。配列は参照によってコピーするため、const b = aは1つの配列に2つの名前を提供し、どちらかを通じてミュータブル化すると両方をヒットします。それはconst配列が依然としてミュータブルである理由と同じです。独立したコピーのために[...original]を使用し、それは浅いことを念頭に置いて、これはまさに数字と文字列の配列に対してあなたが望むものです。
Juno配列は参照によって保持される 配列は参照により保持されるオブジェクトであるため、割り当ては全ての名前がすべての変化を見えるポインタをコピーします。それがconst(参照を修正)がミュータビリティ(ターゲットを変更)と分割される理由です。そして、それは受け取った配列をミュータブル化する関数がその参照を保有している全員のためにそれを変更する場合が、所定の場所で変更よりも新しい配列を好む場合です。スプレッドは浅いコピーを作成し、トップレベルで独立していますが、入れ子配列を共有しています。配列に何か到達してください。順序とカウントは重要です。そしてオブジェクトはキーで物事を検索したいときです。

配列がここからどこに進むか

配列は1つの名前の下に順序付きリストを与えます:[]で作成し、0からインデックスで読み取り、pushpopで変更し、for...ofで歩きます。この章の過去を運ぶ1つの考えは、配列が参照により保持されるため、変数をコピーすると、それを複製するのではなく、リストを共有することです。

自然な次のステップは1つの配列を別の配列に変えること、リストをフィルタリング、全ての項目を変換、すべてを追加し、ループを手で書かずに。それは配列メソッドです。位置ではなく名前で値を検索する必要があるときは、オブジェクトはそのための構造です。