配列には多くのメソッドが用意されています。理解しやすくするために、この章ではそれらをグループに分けて説明します。
アイテムの追加/削除
先頭または末尾からアイテムを追加および削除するメソッドはすでに知っています。
arr.push(...items)
– 末尾にアイテムを追加します。arr.pop()
– 末尾からアイテムを取り出します。arr.shift()
– 先頭からアイテムを取り出します。arr.unshift(...items)
– 先頭にアイテムを追加します。
他にいくつかのメソッドがあります。
splice
配列から要素を削除するにはどうすればよいでしょうか?
配列はオブジェクトなので、delete
を使用してみることができます。
let arr = ["I", "go", "home"];
delete arr[1]; // remove "go"
alert( arr[1] ); // undefined
// now arr = ["I", , "home"];
alert( arr.length ); // 3
要素は削除されましたが、配列にはまだ3つの要素があり、arr.length == 3
であることがわかります。
これは当然のことです。なぜなら、delete obj.key
はkey
によって値を削除するだけだからです。オブジェクトにはそれで問題ありません。しかし、配列の場合、通常は残りの要素がシフトして空いた場所を埋めることを期待します。配列が短くなることを期待します。
そのため、特別なメソッドを使用する必要があります。
arr.splice メソッドは、配列の万能ナイフです。要素の挿入、削除、置換など、あらゆることを実行できます。
構文は次のとおりです。
arr.splice(start[, deleteCount, elem1, ..., elemN])
インデックスstart
から始まるarr
を変更します。deleteCount
個の要素を削除し、それらの場所にelem1, ..., elemN
を挿入します。削除された要素の配列を返します。
このメソッドは、例を見ると簡単に理解できます。
削除から始めましょう。
let arr = ["I", "study", "JavaScript"];
arr.splice(1, 1); // from index 1 remove 1 element
alert( arr ); // ["I", "JavaScript"]
簡単でしょう?インデックス1
から開始して、1
個の要素を削除しました。
次の例では、3つの要素を削除し、他の2つの要素に置き換えます。
let arr = ["I", "study", "JavaScript", "right", "now"];
// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");
alert( arr ) // now ["Let's", "dance", "right", "now"]
ここで、splice
が削除された要素の配列を返すことがわかります。
let arr = ["I", "study", "JavaScript", "right", "now"];
// remove 2 first elements
let removed = arr.splice(0, 2);
alert( removed ); // "I", "study" <-- array of removed elements
splice
メソッドは、削除なしで要素を挿入することもできます。そのためには、deleteCount
を0
に設定する必要があります。
let arr = ["I", "study", "JavaScript"];
// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");
alert( arr ); // "I", "study", "complex", "language", "JavaScript"
ここや他の配列メソッドでは、負のインデックスが許可されています。ここでは、配列の末尾からの位置を指定します。
let arr = [1, 2, 5];
// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);
alert( arr ); // 1,2,3,4,5
slice
arr.sliceメソッドは、よく似たarr.splice
よりもはるかにシンプルです。
構文は次のとおりです。
arr.slice([start], [end])
インデックスstart
からend
(end
は含まない)までのすべてのアイテムをコピーした新しい配列を返します。start
とend
の両方を負にすることができます。その場合、配列の末尾からの位置が想定されます。
これは文字列メソッドstr.slice
に似ていますが、部分文字列の代わりに、部分配列を作成します。
例えば
let arr = ["t", "e", "s", "t"];
alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
引数なしで呼び出すこともできます。arr.slice()
は、arr
のコピーを作成します。これは、元の配列に影響を与えないように、さらに変換するためにコピーを取得するためによく使用されます。
concat
arr.concatメソッドは、他の配列と追加のアイテムからの値を含む新しい配列を作成します。
構文は次のとおりです。
arr.concat(arg1, arg2...)
任意の数の引数(配列または値)を受け入れます。
結果は、arr
からのアイテム、次にarg1
、arg2
などを含む新しい配列です。
引数argN
が配列の場合、そのすべての要素がコピーされます。それ以外の場合、引数自体がコピーされます。
例えば
let arr = [1, 2];
// create an array from: arr and [3,4]
alert( arr.concat([3, 4]) ); // 1,2,3,4
// create an array from: arr and [3,4] and [5,6]
alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6
// create an array from: arr and [3,4], then add values 5 and 6
alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6
通常、配列からの要素のみをコピーします。配列のように見える場合でも、他のオブジェクトは全体として追加されます。
let arr = [1, 2];
let arrayLike = {
0: "something",
length: 1
};
alert( arr.concat(arrayLike) ); // 1,2,[object Object]
ただし、配列のようなオブジェクトに特別なSymbol.isConcatSpreadable
プロパティがある場合、それはconcat
によって配列として扱われます。その代わりに、要素が追加されます。
let arr = [1, 2];
let arrayLike = {
0: "something",
1: "else",
[Symbol.isConcatSpreadable]: true,
length: 2
};
alert( arr.concat(arrayLike) ); // 1,2,something,else
反復処理: forEach
arr.forEachメソッドを使用すると、配列のすべての要素に対して関数を実行できます。
構文
arr.forEach(function(item, index, array) {
// ... do something with an item
});
たとえば、これは配列の各要素を表示します。
// for each element call alert
["Bilbo", "Gandalf", "Nazgul"].forEach(alert);
そして、このコードは、ターゲット配列でのそれらの位置についてより詳しく説明します。
["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
alert(`${item} is at index ${index} in ${array}`);
});
関数(戻り値がある場合)の結果は破棄され、無視されます。
配列の検索
次に、配列を検索するメソッドについて説明します。
indexOf/lastIndexOf と includes
arr.indexOfとarr.includesメソッドは、同様の構文を持ち、基本的に文字列の対応物と同じことを行いますが、文字の代わりにアイテムに対して操作します。
arr.indexOf(item, from)
– インデックスfrom
から始まるitem
を探し、見つかったインデックスを返し、見つからない場合は-1
を返します。arr.includes(item, from)
– インデックスfrom
から始まるitem
を探し、見つかった場合はtrue
を返します。
通常、これらのメソッドは、検索するitem
という1つの引数のみで使用されます。デフォルトでは、検索は先頭から行われます。
例えば
let arr = [1, 0, false];
alert( arr.indexOf(0) ); // 1
alert( arr.indexOf(false) ); // 2
alert( arr.indexOf(null) ); // -1
alert( arr.includes(1) ); // true
indexOf
は比較に厳密な等価性===
を使用することに注意してください。したがって、false
を探している場合、ゼロではなく正確にfalse
を見つけます。
配列にitem
が存在するかどうかを確認したいだけで、インデックスが必要ない場合は、arr.includes
が推奨されます。
arr.lastIndexOfメソッドはindexOf
と同じですが、右から左に検索します。
let fruits = ['Apple', 'Orange', 'Apple']
alert( fruits.indexOf('Apple') ); // 0 (first Apple)
alert( fruits.lastIndexOf('Apple') ); // 2 (last Apple)
includes
メソッドはNaN
を正しく処理します。includes
の小さな、しかし注目すべき機能は、indexOf
とは異なり、NaN
を正しく処理することです。
const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (wrong, should be 0)
alert( arr.includes(NaN) );// true (correct)
これは、includes
がJavaScriptにはるかに後で追加され、内部的に最新の比較アルゴリズムを使用しているためです。
find と findIndex/findLastIndex
オブジェクトの配列があると想像してください。特定の条件を持つオブジェクトをどのように見つけますか?
ここで、arr.find(fn)メソッドが役立ちます。
構文は次のとおりです。
let result = arr.find(function(item, index, array) {
// if true is returned, item is returned and iteration is stopped
// for falsy scenario returns undefined
});
関数は配列の要素に対して、次々に呼び出されます。
item
は要素です。index
はそのインデックスです。array
は配列自体です。
true
を返すと、検索が停止され、item
が返されます。何も見つからない場合は、undefined
が返されます。
たとえば、id
とname
フィールドを持つユーザーの配列があります。id == 1
のユーザーを見つけましょう。
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
let user = users.find(item => item.id == 1);
alert(user.name); // John
実生活では、オブジェクトの配列は一般的なものであるため、find
メソッドは非常に役立ちます。
例では、1つの引数を持つ関数item => item.id == 1
をfind
に提供していることに注意してください。これは一般的であり、この関数の他の引数はめったに使用されません。
arr.findIndexメソッドは、同じ構文を持ちますが、要素自体ではなく、要素が見つかったインデックスを返します。何も見つからない場合は、-1
の値が返されます。
arr.findLastIndexメソッドはfindIndex
に似ていますが、lastIndexOf
と同様に、右から左に検索します。
例を次に示します。
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"},
{id: 4, name: "John"}
];
// Find the index of the first John
alert(users.findIndex(user => user.name == 'John')); // 0
// Find the index of the last John
alert(users.findLastIndex(user => user.name == 'John')); // 3
filter
find
メソッドは、関数がtrue
を返す単一(最初)の要素を探します。
多数ある可能性がある場合は、arr.filter(fn)を使用できます。
構文はfind
に似ていますが、filter
は一致するすべての要素の配列を返します。
let results = arr.filter(function(item, index, array) {
// if true item is pushed to results and the iteration continues
// returns empty array if nothing found
});
例えば
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
// returns array of the first two users
let someUsers = users.filter(item => item.id < 3);
alert(someUsers.length); // 2
配列の変換
次に、配列を変換および並べ替えるメソッドに進みましょう。
map
arr.mapメソッドは、最も便利でよく使用されるメソッドの1つです。
配列の各要素に対して関数を呼び出し、結果の配列を返します。
構文は次のとおりです。
let result = arr.map(function(item, index, array) {
// returns the new value instead of item
});
たとえば、ここでは各要素をその長さに変換します。
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6
sort(fn)
arr.sort()の呼び出しは、配列をその場でソートし、要素の順序を変更します。
また、ソートされた配列を返しますが、arr
自体が変更されるため、戻り値は通常無視されます。
例えば
let arr = [ 1, 2, 15 ];
// the method reorders the content of arr
arr.sort();
alert( arr ); // 1, 15, 2
結果に何か奇妙なことに気づきましたか?
順序が1, 15, 2
になりました。正しくありません。しかし、なぜでしょうか?
アイテムはデフォルトで文字列としてソートされます。
文字通り、すべての要素は比較のために文字列に変換されます。文字列の場合、辞書順が適用され、実際には "2" > "15"
となります。
独自のソート順を使用するには、arr.sort()
の引数として関数を指定する必要があります。
この関数は、任意の2つの値を比較し、次の値を返す必要があります。
function compare(a, b) {
if (a > b) return 1; // if the first value is greater than the second
if (a == b) return 0; // if values are equal
if (a < b) return -1; // if the first value is less than the second
}
たとえば、数値としてソートするには、
function compareNumeric(a, b) {
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}
let arr = [ 1, 2, 15 ];
arr.sort(compareNumeric);
alert(arr); // 1, 2, 15
これで意図したとおりに動作します。
少し寄り道して、何が起こっているかを考えてみましょう。arr
はどんなものでも配列にすることができますね?数値、文字列、オブジェクトなど、何でも入れることができます。つまり、いくつかのアイテムのセットがあるということです。それをソートするには、要素を比較する方法を知っている順序付け関数が必要です。デフォルトは文字列順です。
arr.sort(fn)
メソッドは、一般的なソートアルゴリズムを実装しています。内部でどのように動作するか(最適化された クイックソート または ティムソート がほとんどの場合)を気にする必要はありません。配列を走査し、提供された関数を使用して要素を比較し、並べ替えます。私たちに必要なのは、比較を行う fn
を提供することだけです。
ところで、どの要素が比較されているかを知りたい場合は、アラートで表示することもできます。
[1, -2, 15, 2, 0, 8].sort(function(a, b) {
alert( a + " <> " + b );
return a - b;
});
アルゴリズムは、処理中に要素を他の複数の要素と比較する可能性がありますが、できるだけ比較回数を少なくしようとします。
実際には、比較関数は「大きい」ことを示すために正の数を、「小さい」ことを示すために負の数を返すだけで十分です。
これにより、より短い関数を書くことができます。
let arr = [ 1, 2, 15 ];
arr.sort(function(a, b) { return a - b; });
alert(arr); // 1, 2, 15
アロー関数 を覚えていますか?ここでは、より簡潔なソートのためにそれらを使用できます。
arr.sort( (a, b) => a - b );
これは、上記の長いバージョンとまったく同じように動作します。
localeCompare
を使用します。文字列 の比較アルゴリズムを覚えていますか?デフォルトでは、文字をコードで比較します。
多くのアルファベットでは、Ö
のような文字を正しくソートするために、str.localeCompare
メソッドを使用する方が適切です。
たとえば、ドイツ語でいくつかの国をソートしてみましょう。
let countries = ['Österreich', 'Andorra', 'Vietnam'];
alert( countries.sort( (a, b) => a > b ? 1 : -1) ); // Andorra, Vietnam, Österreich (wrong)
alert( countries.sort( (a, b) => a.localeCompare(b) ) ); // Andorra,Österreich,Vietnam (correct!)
逆順にする
arr.reverse メソッドは、arr
内の要素の順序を反転させます。
例えば
let arr = [1, 2, 3, 4, 5];
arr.reverse();
alert( arr ); // 5,4,3,2,1
また、反転後の配列 arr
を返します。
split と join
実際の状況を考えてみましょう。メッセージングアプリを作成中で、ユーザーがコンマ区切りの受信者リストを入力します: John, Pete, Mary
。しかし、私たちにとっては、単一の文字列よりも名前の配列の方がはるかに使いやすいでしょう。どうすれば取得できるでしょうか?
str.split(delim) メソッドは、まさにそれを行います。文字列を、指定された区切り文字 delim
で分割して配列にします。
以下の例では、コンマとスペースで分割しています。
let names = 'Bilbo, Gandalf, Nazgul';
let arr = names.split(', ');
for (let name of arr) {
alert( `A message to ${name}.` ); // A message to Bilbo (and other names)
}
split
メソッドには、オプションの2番目の数値引数があります。これは配列の長さに制限を加えます。これが指定された場合、余分な要素は無視されます。実際には、めったに使用されません。
let arr = 'Bilbo, Gandalf, Nazgul, Saruman'.split(', ', 2);
alert(arr); // Bilbo, Gandalf
空の s
を使用して split(s)
を呼び出すと、文字列は文字の配列に分割されます。
let str = "test";
alert( str.split('') ); // t,e,s,t
arr.join(glue) の呼び出しは、split
の逆を行います。arr
アイテムを glue
で結合した文字列を作成します。
例えば
let arr = ['Bilbo', 'Gandalf', 'Nazgul'];
let str = arr.join(';'); // glue the array into a string using ;
alert( str ); // Bilbo;Gandalf;Nazgul
reduce/reduceRight
配列を反復処理する必要がある場合は、forEach
、for
、または for..of
を使用できます。
各要素のデータを反復処理して返す必要がある場合は、map
を使用できます。
arr.reduce と arr.reduceRight メソッドもその仲間ですが、少し複雑です。これらは、配列に基づいて単一の値を計算するために使用されます。
構文は次のとおりです。
let value = arr.reduce(function(accumulator, item, index, array) {
// ...
}, [initial]);
関数は、すべての配列要素に1つずつ順番に適用され、その結果を次の呼び出しに「引き継ぎます」。
引数
accumulator
– 前の関数呼び出しの結果です。(initial
が提供されている場合は)最初はinitial
と等しくなります。item
– 現在の配列要素です。index
– その位置です。array
– 配列です。
関数が適用されると、前の関数呼び出しの結果が最初の引数として次の呼び出しに渡されます。
したがって、最初の引数は本質的に、以前のすべての実行の結合結果を格納するアキュムレータです。そして最後に、reduce
の結果になります。
複雑に聞こえますか?
それを理解する最も簡単な方法は、例によるものです。
ここでは、1行で配列の合計を取得しています。
let arr = [1, 2, 3, 4, 5];
let result = arr.reduce((sum, current) => sum + current, 0);
alert(result); // 15
reduce
に渡される関数は、通常はこれで十分な2つの引数のみを使用します。
何が起こっているかの詳細を見てみましょう。
- 最初の実行では、
sum
はinitial
値(reduce
の最後の引数)であり、0
に等しく、current
は最初の配列要素であり、1
に等しいです。したがって、関数の結果は1
です。 - 2回目の実行では、
sum = 1
で、2番目の配列要素 (2
) をそれに追加して返します。 - 3回目の実行では、
sum = 3
で、さらに別の要素を追加します。以下同様です…
計算フロー
または、表形式では、各行が次の配列要素に対する関数呼び出しを表します。
合計 |
現在 |
結果 | |
---|---|---|---|
最初の呼び出し | 0 |
1 |
1 |
2回目の呼び出し | 1 |
2 |
3 |
3回目の呼び出し | 3 |
3 |
6 |
4回目の呼び出し | 6 |
4 |
10 |
5回目の呼び出し | 10 |
5 |
15 |
ここでは、前の呼び出しの結果が次の呼び出しの最初の引数になる様子が明確にわかります。
初期値を省略することもできます。
let arr = [1, 2, 3, 4, 5];
// removed initial value from reduce (no 0)
let result = arr.reduce((sum, current) => sum + current);
alert( result ); // 15
結果は同じです。これは、初期値がない場合、reduce
が配列の最初の要素を初期値として取得し、2番目の要素から反復を開始するためです。
計算表は上記と同じですが、最初の行がありません。
ただし、このような使用には細心の注意が必要です。配列が空の場合、初期値のない reduce
呼び出しはエラーになります。
例を次に示します。
let arr = [];
// Error: Reduce of empty array with no initial value
// if the initial value existed, reduce would return it for the empty arr.
arr.reduce((sum, current) => sum + current);
そのため、常に初期値を指定することをお勧めします。
arr.reduceRight メソッドは同じことを行いますが、右から左に進みます。
Array.isArray
配列は独立した言語型を形成しません。それらはオブジェクトに基づいています。
したがって、typeof
はプレーンオブジェクトを配列から区別するのに役立ちません。
alert(typeof {}); // object
alert(typeof []); // object (same)
...しかし、配列は非常によく使用されるため、特別なメソッドがあります: Array.isArray(value)。value
が配列の場合 true
を返し、それ以外の場合は false
を返します。
alert(Array.isArray({})); // false
alert(Array.isArray([])); // true
ほとんどのメソッドは "thisArg" をサポートしています。
sort
を除いた、関数を呼び出すほとんどすべての配列メソッド(find
、filter
、map
など)は、オプションの追加パラメータ thisArg
を受け入れます。
このパラメータはめったに使用されないため、上記のセクションでは説明されていません。ただし、完全を期すために、説明する必要があります。
これらのメソッドの完全な構文は次のとおりです。
arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
// ...
// thisArg is the optional last argument
thisArg
パラメータの値は、func
の this
になります。
たとえば、ここで army
オブジェクトのメソッドをフィルタとして使用し、thisArg
がコンテキストを渡します。
let army = {
minAge: 18,
maxAge: 27,
canJoin(user) {
return user.age >= this.minAge && user.age < this.maxAge;
}
};
let users = [
{age: 16},
{age: 20},
{age: 23},
{age: 30}
];
// find users, for who army.canJoin returns true
let soldiers = users.filter(army.canJoin, army);
alert(soldiers.length); // 2
alert(soldiers[0].age); // 20
alert(soldiers[1].age); // 23
上記の例で users.filter(army.canJoin)
を使用した場合、army.canJoin
はスタンドアロン関数として呼び出され、this=undefined
になり、すぐにエラーが発生します。
users.filter(army.canJoin, army)
の呼び出しは、users.filter(user => army.canJoin(user))
に置き換えることができ、同じことを行います。後者の方が、ほとんどの人にとって理解しやすいので、より頻繁に使用されます。
まとめ
配列メソッドの早見表
-
要素を追加/削除するには
push(...items)
– 末尾にアイテムを追加します。pop()
– 末尾からアイテムを抽出します。shift()
– 先頭からアイテムを抽出します。unshift(...items)
– 先頭にアイテムを追加します。splice(pos, deleteCount, ...items)
– インデックスpos
で、deleteCount
個の要素を削除し、items
を挿入します。slice(start, end)
– 新しい配列を作成し、インデックスstart
からend
(非包含)までの要素をそこにコピーします。concat(...items)
– 新しい配列を返します。現在の配列のすべてのメンバーをコピーし、そこにitems
を追加します。items
のいずれかが配列の場合、その要素が取得されます。
-
要素を検索するには
indexOf/lastIndexOf(item, pos)
– 位置pos
からitem
を検索し、インデックスを返します。見つからない場合は-1
を返します。includes(value)
– 配列にvalue
がある場合はtrue
を返し、それ以外の場合はfalse
を返します。find/filter(func)
– 関数を通して要素をフィルタリングし、true
を返す最初の/すべての値を返します。findIndex
はfind
と似ていますが、値の代わりにインデックスを返します。
-
要素を反復処理するには
forEach(func)
– すべての要素に対してfunc
を呼び出しますが、何も返しません。
-
配列を変換するには
map(func)
– すべての要素に対してfunc
を呼び出した結果から新しい配列を作成します。sort(func)
– 配列をインプレースでソートしてから、それを返します。reverse()
– 配列をインプレースで反転してから、それを返します。split/join
– 文字列を配列に変換したり、その逆を行ったりします。reduce/reduceRight(func, initial)
– 各要素に対してfunc
を呼び出し、呼び出し間で中間結果を渡すことにより、配列上で単一の値を計算します。
-
追加
Array.isArray(value)
はvalue
が配列であるかどうかを確認し、そうであればtrue
を返し、そうでない場合はfalse
を返します。
sort
、reverse
、および splice
メソッドは、配列自体を変更することに注意してください。
これらのメソッドは最もよく使用されるもので、99%のユースケースをカバーします。しかし、他にもいくつかあります。
-
arr.some(fn)/arr.every(fn) は、配列をチェックします。
関数
fn
は、map
と同様に配列の各要素に対して呼び出されます。いずれかの結果またはすべての結果がtrue
の場合はtrue
を返し、それ以外の場合はfalse
を返します。これらのメソッドは、
||
および&&
演算子と似たような動作をします。もしfn
が truthy な値を返すと、arr.some()
は直ちにtrue
を返し、残りのアイテムに対するイテレーションを停止します。もしfn
が falsy な値を返すと、arr.every()
は直ちにfalse
を返し、同様に残りのアイテムに対するイテレーションを停止します。every
を使用して配列を比較できます。function arraysEqual(arr1, arr2) { return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]); } alert( arraysEqual([1, 2], [1, 2])); // true
-
arr.fill(value, start, end) – 配列のインデックス
start
からend
までを、繰り返しvalue
で埋めます。 -
arr.copyWithin(target, start, end) – 位置
start
から位置end
までの要素を、位置target
(既存のものを上書きします) に自身にコピーします。 -
arr.flat(depth)/arr.flatMap(fn) は、多次元配列から新しいフラットな配列を作成します。
完全なリストについては、マニュアルを参照してください。
一見すると、非常に多くのメソッドがあり、覚えるのがかなり難しいように思えるかもしれません。しかし実際には、ずっと簡単です。
チートシートに目を通し、それらを把握してください。次に、この章のタスクを解いて練習し、配列メソッドの経験を積んでください。
その後、配列で何かをしたいときに、どうすればいいかわからない場合は、ここに戻ってきて、チートシートを見て、適切なメソッドを見つけてください。例は、正しく書くのに役立ちます。すぐに、特別な努力をしなくても、メソッドを自動的に覚えるでしょう。
コメント
<code>
タグを使用し、複数行の場合は<pre>
タグで囲み、10 行を超える場合はサンドボックスを使用してください (plnkr、jsbin、codepen…)