部分取得を一言でいうと(slice / substring の役割)
文字列の「部分だけ」を取り出したいことは、実務でも学習でも山ほど出てきます。
先頭3文字だけ欲しい
後ろから2文字だけ欲しい
5文字目から10文字目の手前まで欲しい
こういうときに使うのが、slice と substring です。
ここが重要です。slice と substring はどちらも「文字列の一部を取り出すメソッド」ですが、
細かいルールや“クセ”が違います。
基本的には slice をメインで使い、substring は「そういうのもある」と理解しておく くらいで十分です。
前提復習:インデックスと length の関係
インデックスは 0 から始まる
文字列の各文字にはインデックス(位置の番号)が付きます。
JavaScript では 0 から始まります。
const text = "JavaScript";
// J a v a S c r i p t
// 0 1 2 3 4 5 6 7 8 9
JavaScripttext[0] → "J"text[4] → "S"
といった具合です。
length と最後のインデックス
text.length は文字数です。
console.log(text.length); // 10
JavaScript最後のインデックスは length - 1 なので、この場合は 9 です。
ここが重要です。
「0 から始まる」「最後は length – 1」という 2つのルールを頭に入れておくと、
このあとの slice / substring の「開始位置」「終了位置」が理解しやすくなります。
slice の基本:開始位置と終了位置(終了は“手前まで”)
基本形:slice(開始, 終了)
slice の基本的な形はこうです。
文字列.slice(開始インデックス, 終了インデックス)
JavaScriptここでの重要ポイントは、
終了インデックスの位置は「含まれない(手前まで)」 ということです。
具体例で感覚をつかむ
const text = "JavaScript";
// インデックス: 0 1 2 3 4 5 6 7 8 9
const part1 = text.slice(0, 4);
console.log(part1); // "Java"
JavaScript0 から始めて、4 の手前(3 まで)を取り出しています。
取り出される範囲は「0,1,2,3」の文字 → "Java"
もう一つ。
const part2 = text.slice(4, 10);
console.log(part2); // "Script"
JavaScript4 から始めて、10 の手前(9 まで)。
「4,5,6,7,8,9」の文字 → "Script"
終了インデックスを省略した場合
終了インデックスを省略すると、
開始位置から最後まで になります。
const text = "JavaScript";
const part3 = text.slice(4);
console.log(part3); // "Script"
JavaScriptこれは先ほどの slice(4, 10) と同じ結果になります。
ここが重要です。slice(開始, 終了) は「開始を含み、終了の“手前まで”」。slice(開始) は「開始から最後まで」。
この「終了は含まない」というルールは、配列の slice と共通です。
slice の便利ポイント:負のインデックスで「後ろから」指定できる
負の値は「末尾から数える」
slice の大きな特徴は、
負のインデックスを使える ことです。
const text = "JavaScript";
// J a v a S c r i p t
// 0 1 2 3 4 5 6 7 8 9
// -10 -9 -8 -7 -6 -5 -4 -3 -2 -1(負の数で見るとこういうイメージ)
JavaScript例えば、最後の 3 文字が欲しい場合。
const last3 = text.slice(-3);
console.log(last3); // "ipt"
JavaScript-3 は「後ろから 3 文字分」の意味で、
その位置から最後までを切り出しています。
負の開始と正の終了の組み合わせ
例えば、
「後ろから4文字目から、後ろから1文字前まで」
のような指定もできます。
const text = "JavaScript";
const part = text.slice(-4, -1);
console.log(part); // "rip"
JavaScript-4 → インデックス 6(”r”)-1 → インデックス 9 の「手前」 → 8(”p”)
なので、
6,7,8 → "rip" になります。
実務でよくあるパターン
ファイル名の拡張子を取りたい、といった場合にも使えます。
const fileName = "image.png";
const ext = fileName.slice(-3);
console.log(ext); // "png"
JavaScriptここが重要です。
負のインデックスが使えるのは slice の強み。
「後ろから◯文字」といった指定をするとき、slice(-3) のような書き方はかなり実務的です。
substring の基本:似ているけどクセが違う
基本形:substring(開始, 終了)
substring も基本形は同じに見えます。
文字列.substring(開始インデックス, 終了インデックス)
JavaScript終了インデックスも同じく「手前まで」です。
const text = "JavaScript";
const part1 = text.substring(0, 4);
console.log(part1); // "Java"
JavaScriptぱっと見は slice と同じですね。
substring の特殊ルール①:開始 > 終了 なら入れ替える
substring の特徴的なルールがこれです。
const text = "JavaScript";
console.log(text.substring(4, 0)); // "Java"
JavaScriptsubstring(4, 0) と書いても、
JavaScript が内部で「小さい方を開始、大きい方を終了」に入れ替えてくれます。
つまり、
substring(4, 0) → 実際には substring(0, 4) として動く
ということです。
一方、slice はこうなりません。
console.log(text.slice(4, 0)); // ""(空文字)
JavaScriptslice は「開始が終了より大きい」場合は、
空文字を返す のがルールです。
substring の特殊ルール②:負の値はすべて 0 扱い
substring に負の値を渡すと、その値は 0 に変換されます。
const text = "JavaScript";
console.log(text.substring(-3)); // "JavaScript"(-3 → 0 とみなされる)
console.log(text.substring(-3, 4)); // "Java"
JavaScriptsubstring(-3) は、実際には substring(0) と同じ動きになります。
これも slice とは違うところです。
console.log(text.slice(-3)); // "ipt"(負のインデックスがちゃんと効く)
JavaScriptここが重要です。substring は「インデックスの大小を自動で入れ替える」「負の数を 0 に丸める」という“親切風”の挙動をします。
一方で、slice は「負の値は末尾から」「開始 > 終了なら空文字」と、より素直で予測しやすいルールです。
slice と substring、どちらを使うべきか
結論:基本的には slice をおすすめする
理由はシンプルで、
負のインデックスが使えて表現力が高い
挙動が「開始から終了の手前まで」と素直
開始 > 終了 や 負の値を勝手に修正しないので、バグに気づきやすい
からです。
例えば、「後ろから 3 文字だけ取りたい」は、slice ならこう書けます。
const last3 = text.slice(-3);
JavaScriptsubstring ではこうはいきません。
自分で text.length - 3 のように計算する必要があります。
const last3 = text.substring(text.length - 3);
JavaScriptそれでも substring が存在している理由
歴史的には、substring のほうが古くからあり、slice があとから追加された、という流れがあります(もともとは配列用に導入されたもの)。
レガシーなコードや古い本には、substring の例がたくさん残っています。
しかし、今から新しく書くコードでは、
「部分取得は基本 slice を使う」
「substring は既存コードを読むときに“クセを理解しておく”程度」
というスタンスで問題ありません。
具体的な例題で違いを体感する
例1:先頭5文字を取り出す
text = "JavaScript" の先頭 5 文字 → "JavaS" を取りたい。
const text = "JavaScript";
console.log(text.slice(0, 5)); // "JavaS"
console.log(text.substring(0, 5)); // "JavaS"
JavaScriptここでは両方同じ動きです。
例2:インデックス4〜7を取り出す(4,5,6)
text[4]〜text[6] → "Scr" を取りたい。
console.log(text.slice(4, 7)); // "Scr"
console.log(text.substring(4, 7)); // "Scr"
JavaScriptここも同じです。
例3:開始 > 終了 のとき
console.log(text.slice(7, 4)); // ""(空文字)
console.log(text.substring(7, 4)); // "Scr"(4〜7 に勝手に入れ替わる)
JavaScriptslice は「そんな範囲はないね」と空文字を返すsubstring は「順番間違えてるみたいだから直しといたよ」と入れ替える
という違いが出ます。
例4:負のインデックス
console.log(text.slice(-6)); // "Script"
console.log(text.substring(-6)); // "JavaScript"(-6 → 0)
JavaScriptslice(-6) は「後ろから6文字」substring(-6) は「0 から最後まで」
となり、全く違う結果になります。
ここが重要です。
「後ろから何文字」といった操作や、「インデックスの大小で挙動を変えたくない」ときは、slice のほうが直感的で安全。substring は“自動修正”が入る分、「意図しない動き」に気付きにくくなることがあります。
部分取得は「元の文字列を変えない」ことも重要
文字列はイミュータブル(変更不可)
slice / substring の共通の性質として、
どちらも“元の文字列を変更しない” という点があります。
const text = "JavaScript";
const part = text.slice(0, 4);
console.log(part); // "Java"
console.log(text); // "JavaScript"(元はそのまま)
JavaScriptsubstring も同じです。
const part2 = text.substring(4);
console.log(part2); // "Script"
console.log(text); // "JavaScript"
JavaScript文字列はイミュータブル(変更できない)なので、
操作をしても常に「新しい文字列」が返ってくるだけ です。
ここが重要です。slice や substring を使っても、“切り出した結果”は元から独立した文字列。
元の文字列は汚さない。
安心して何度でも部分取得を行える、という感覚を持っておいてください。
初心者として押さえるべき「部分取得」の核心
最後に、slice / substring を使った部分取得で、本当に大事なポイントだけまとめます。
文字列の部分取得は、slice と substring のどちらでもできるが、
基本的には slice を使うほうが直感的で安全。
どちらも「開始インデックスを含み、終了インデックスの“手前まで”」を切り出す。slice(start, end) / slice(start) という形で使う。
slice は負のインデックスを受け付け、「後ろから◯文字」といった指定ができる。substring は負のインデックスを 0 に丸めてしまうので、後ろからの指定には向かない。
substring は「開始 > 終了」の場合に自動で入れ替える (substring(7,4) → 実質 substring(4,7))、slice はその場合は空文字を返す。
どちらも元の文字列を変更せず、「新しい文字列」を返すだけ。
ここが重要です。
まずは slice を使いこなすことに集中し、「開始〜終了の手前まで」「負のインデックスで後ろから」この2つを体に染み込ませる。substring は、「古いコードを読んだときに“ああ、開始と終了を入れ替えちゃうあれね”と分かる程度で十分です。
練習としては、次のようなコードを自分で書いてみるといいです。
const text = "JavaScript";
console.log(text.slice(0, 4)); // 先頭4文字
console.log(text.slice(4)); // 5文字目以降
console.log(text.slice(-3)); // 最後の3文字
console.log(text.slice(2, -2)); // 3文字目から、後ろ2文字を除いたところまで
JavaScriptそれぞれの結果を予想してから実行してみてください。
「インデックス」「length」「開始含む/終了手前まで」というルールが、自分の中でどれだけ定着しているか、すぐに分かるはずです。
