String

String オブジェクトは文字の並びを表したり操作したりするために使用されます。

解説

文字列は、テキスト形式で表現可能なデータを保持するのに便利です。最もよく使われる操作として、文字列の長さをチェックする length プロパティ、 文字列に対する + および += 演算子を用いた文字列の連結、文字列の中の部分文字列の存在や位置をチェックする indexOf() メソッド、部分文字列を取り出す substring() メソッドが挙げられます。

文字列の生成

文字列は文字列リテラルからプリミティブとして、または String() コンストラクターを使用してオブジェクトとして生成することができます。

js
const string1 = "文字列プリミティブ";
const string2 = 'これも文字列プリミティブ';
const string3 = `別な文字列プリミティブ`;
js
const string4 = new String("文字列オブジェクト");

文字列プリミティブと文字列オブジェクトは多くの動作を共有していますが、その他に重要な相違点と注意点があります。 下記の「文字列プリミティブと String オブジェクト」を参照してください。

文字列リテラルは単一引用符または二重引用符を使用して指定することができ、どちらでも同様に扱われますが、逆引用符文字 ` を使用することもできます。最後の形はテンプレートリテラルを指定しています。この形式では式を補完することができます。文字列リテラルの構文については、字句文法を参照してください。

文字へのアクセス

文字列内の個々の文字へのアクセス方法には、2 通りの方法があります。そのひとつは charAt() メソッドです。

js
"ねこ".charAt(1); // "こ" が返される

他にも、文字列を配列風のオブジェクトとして扱い、個々の文字を数値インデックスに対応させる方法もあります。

js
"ねこ"[1]; // "こ" が返される。

ブラケット記法を使用した文字アクセスでは、これらのプロパティに値を設定したり削除したりすることはできません。関連するプロパティを書き込んだり設定したりすることもできません。(より詳細な情報は Object.defineProperty() を参照してください。)

文字列の比較

文字列を比較するには小なり / 大なり演算子を用います。

js
const a = "a";
const b = "b";
if (a < b) {
  // true
  console.log(`${a}${b} より小さい`);
} else if (a > b) {
  console.log(`${a}${b} より大きい`);
} else {
  console.log(`${a}${b} は等しい`);
}

なお、すべての比較演算子は、=== および == を含め、文字列を大文字小文字を区別して比較します。文字列の大文字小文字を区別せずに比較する一般的な方法は、両方の文字列を同じ種類(大文字または小文字)に変換してから比較することです。

js
function areEqualCaseInsensitive(str1, str2) {
  return str1.toUpperCase() === str2.toUpperCase();
}

toUpperCase()toLowerCase() のどちらで変換するかはほとんど自由ですが、ラテン文字以外に広げると、どちらが完全に堅牢なとは言えません。例えば、ドイツ語の小文字 ßsstoUpperCase() によってどちらも SS に変換されますが、トルコ語の文字 ıtoLocaleLowerCase("tr") を使用しない限り、 toLowerCase() によって I と等しくない文字として誤って報告されてしまいます。

js
const areEqualInUpperCase = (str1, str2) =>
  str1.toUpperCase() === str2.toUpperCase();
const areEqualInLowerCase = (str1, str2) =>
  str1.toLowerCase() === str2.toLowerCase();

areEqualInUpperCase("ß", "ss"); // true; should be false
areEqualInLowerCase("ı", "I"); // false; should be true

ロケールを意識して大文字と小文字を区別せずに比較するための堅牢な解決策は、Intl.Collator API を使用するか、文字列の localeCompare() メソッド(インターフェイスは同じです)を sensitivity オプションで "accent" または "base" に設定します。

js
const areEqual = (str1, str2, locale = "en-US") =>
  str1.localeCompare(str2, locale, { sensitivity: "accent" }) === 0;

areEqual("ß", "ss", "de"); // false
areEqual("ı", "I", "tr"); // true

localeCompare() メソッドは strcmp() と同様の方法で文字列を比較することができます。ロケールを意識した方法で文字列を並べ替えることができます。

文字列プリミティブと String オブジェクト

JavaScript では、 String オブジェクトとプリミティブ文字列は区別されることに注意してください。(BooleanNumber にも同じことが言えます。)

文字列リテラル(二重引用符または単一引用符で示されます)、および String 関数をコンストラクター以外の場面で(すなわち new キーワードを使わずに)呼び出した場合はプリミティブの文字列になります。 文字列プリミティブに対してメソッドを呼び出したり、プロパティを参照したりするコンテキストでは、JavaScript は自動的に文字列プリミティブをラップし、ラッパーオブジェクトに対してメソッドを呼び出したり、プロパティを参照したりします。

js
const strPrim = "foo"; // リテラルは文字列プリミティブ
const strPrim2 = String(1); // 文字列プリミティブ "1" に変換
const strPrim3 = String(true); // 文字列プリミティブ "true" に変換
const strObj = new String(strPrim); // new を付けて String を呼び出すと文字列ラッパーオブジェクトを返す

console.log(typeof strPrim); // "string"
console.log(typeof strPrim2); // "string"
console.log(typeof strPrim3); // "string"
console.log(typeof strObj); // "object"

警告: String をコンストラクターとして使用することはほとんどないでしょう。

プリミティブの文字列と String オブジェクトは eval() を使用すると異なる結果となります。 eval に渡されたプリミティブは、ソースコードとして扱われます。 String オブジェクトは他のオブジェクトと同様に、オブジェクトとしてそのままの文字列を返します。

js
const s1 = "2 + 2"; // 文字列プリミティブを生成
const s2 = new String("2 + 2"); // String オブジェクトを生成
console.log(eval(s1)); // 数値の 4 を返す
console.log(eval(s2)); // 文字列の "2 + 2" を返す

こういった理由から、プリミティブの文字列を期待して実装されたコードは String オブジェクトでうまく動作しないことがあります。しかし、一般的にはこれらの違いを考慮しなければならないことはあまりありません。

なお、String オブジェクトは valueOf() メソッドを用いることで、プリミティブの文字列に変換することができます。

js
console.log(eval(s2.valueOf())); // 数値の 4 を返す

文字列変換

文字列を期待する組み込み操作の多くは、最初に引数を文字列に変換します(これが String オブジェクトが文字列プリミティブと同じように動作する主な理由です)。処理は以下のように要約できます。

  • 文字列はそのまま返します。
  • undefined"undefined" なります。
  • null"null" になります。
  • true"true" に、false"false" になります。
  • 数値は toString(10) と同じアルゴリズムで変換されます。
  • 長整数toString(10) と同じアルゴリズムで変換されます。
  • シンボルTypeError が発生します。
  • オブジェクトは最初にプリミティブに変換され、これは [@@toPrimitive]() を("string" をヒントとして)呼び出すことで行われ、次に toString()、そして valueOf() メソッドがこの順序で呼び出されます。結果のプリミティブはそれから文字列に変換されます。

JavaScript でほぼ同じ効果を得る方法はいくつかあります。

  • テンプレートリテラル: `${x}` は埋め込まれた式に対して、上記で説明した文字列変換と同じ手順を踏みます。
  • String() 関数: String(x)x を変換するのに同じアルゴリズムを使用しますが、シンボルでも TypeError が発生せず、"Symbol(description)" の形で description にそのシンボルの説明が入ったものを返します。
  • + 演算子: "" + x はオペランドを文字列ではなくプリミティブに変換します。一部のオブジェクトでは、通常の文字列変換とは完全に異なる動作をします。詳しくはリファレンスページを参照してください。

用途によっては `${x}` (組み込みの動作を模倣するため)または String(x)(エラーを発生させずにシンボル値を処理するため)を使用したいかもしれませんが、 "" + x は使用しないでください。

UTF-16 文字、Unicode コードポイント、書記素クラスター

文字列は基本的に UTF-16 コード単位の並びとして表します。UTF-16 エンコーダーでは、すべてのコード単位は正確に 16 ビット長です。つまり、単一の UTF-16 コード単位として表現可能な文字は、最大で 216 個、つまり 65536 通りあります。この文字集合は基本多言語面 (BMP) と呼ばれ、ラテン語、ギリシャ語、キリル文字のような最も一般的な文字や多くの東アジアの文字を含みます。各コード単位は u の文字列の後にちょうど 4 つの 16 進数を続けて書くことができます。

しかし、Unicode の文字集合全体は 65536 よりはるかにずっと大きいのです。追加の文字は UTF-16 でサロゲートペアとして格納されます。これは単一の文字を表す 16 ビットのコード単位のペアです。曖昧さを避けるために、ペアの 2 つの部分は 0xD8000xDFFF の間でなければならず、これらのコード単位は単一のコード単位の文字をエンコードするためには使用しません。(より正確には、高サロゲートは 0xD800 から 0xDBFF までの値があり、低サロゲートは 0xDC00 から 0xDFFF までの値があります)。各 Unicode 文字は、 1 つないし 2 つの UTF-16 コード単位から成っており、Unicode コードポイントとも呼ばれます。各 Unicode コードポイントは文字列の中で \u{xxxxxx} と書くことができ、ここで xxxxxx は 1-6 桁の 16 進数を表します。

「孤立サロゲート」とは、下記の記述のいずれかを満たす 16 ビットのコード単位です。

  • 0xD800 から 0xDBFF までの範囲(つまり高サロゲート)にあるものの、文字列の最後のコード単位であるか、次のコード単位が低サロゲートではないもの。
  • 0xDC00 から 0xDFFF までの範囲(つまり低サロゲート)にあるものの、文字列の最初のコード単位であるか、前のコード単位が高サロゲートではないもの。

孤立サロゲートは Unicode 文字を表しません。すべて UTF-16 コード単位に基づいて動作するため、ほとんどの JavaScript 組み込みメソッドは正しく扱いますが、他のシステムとやりとりするとき、孤立サロゲートはしばしば有効な値ではありません。例えば、encodeURI() は孤立サロゲートがあると URIError が発生します。これは URI エンコーディングが UTF-8 エンコーディングを使用しており、孤立サロゲートに対するエンコーディングを持たないためです。孤立サロゲートを格納しない文字列は well-formed 文字列と呼ばれ、UTF-16 を扱わない関数(encodeURI()TextEncoder など)で使用しても安全です。isWellFormed() メソッドで文字列が整形されているか調べたり、toWellFormed() メソッドで孤立サロゲートをサニタイズすることができます。

Unicode 文字の上に、書記素クラスターと呼ばれる 1 つの視覚単位として扱われるべき Unicode 文字並びがあります。最も一般的なケースは絵文字で、様々なバリエーションがある絵文字の多くは、実際には複数の絵文字で形成されており、たいていの場合、<ZWJ> (U+200D) 文字で結合されています。

どのレベルの文字を反復処理するのかに注意する必要があります。例えば、split("") は UTF-16 コード単位で分割し、サロゲートペアを区切ります。文字列インデックスも各 UTF-16 コード単位のインデックスを参照します。他にも、@@iterator() はUnicode コードポイントで反復処理します。書記素クラスターを反復処理するには独自のコードが必要です。

js
"😄".split(""); // ['\ud83d', '\ude04']; 孤立サロゲートを 2 つに分割

// "Backhand Index Pointing Right: Dark Skin Tone"
[..."👉🏿"]; // ['👉', '🏿']
// 基本的な "Backhand Index Pointing Right" の絵文字と
// "Dark skin tone" の絵文字に分割

// "Family: Man, Boy"
[..."👨‍👦"]; // [ '👨', '‍', '👦' ]
// "Man" と "Boy" の絵文字を ZWJ で結合

// アメリカの国旗
[..."🇺🇳"]; // [ '🇺', '🇳' ]
// 2 つの "region indicator" 文字である "U" と "N"
// すべての国旗の絵文字は、2 文字の地域識別文字を結合することで構成されている

コンストラクター

String()

新しい String オブジェクトを生成するために使用します。コンストラクターではなく関数として呼び出されたときは型変換を行うので、普通はより有用です。

静的メソッド

String.fromCharCode()

指定された Unicode 値の並びから生成した文字列を返します。

String.fromCodePoint()

指定された Unicode コードポイントの並びから生成した文字列を返します。

String.raw()

生のテンプレート文字列から生成した文字列を返します。

インスタンスプロパティ

以下のプロパティは String.prototype で定義されており、すべての String インスタンスで共有されます。

String.prototype.constructor

インスタンスオブジェクトを作成したコンストラクター関数。文字列インスタンスの場合、初期値は String コンストラクターです。

以下のプロパティはそれぞれの String インスタンスに固有のプロパティです。

length

文字列の length を反映します。読み取り専用です。

インスタンスメソッド

String.prototype.at()

指定した index にある文字(UTF-16 コード単位)を返します。負の整数を受け入れ、その場合は文字列の最後の文字から遡ります。

String.prototype.charAt()

index で指定された位置の文字(UTF-16 コード単位 1 つ)を返します。

String.prototype.charCodeAt()

index で指定された位置の文字の UTF-16 コード単位の値を示す数を返します。

String.prototype.codePointAt()

pos で指定された位置から始まる UTF-16 エンコードされた際のコードポイントの、コードポイントの値である正の整数を返します。

String.prototype.concat()

2 つ(以上)の文字列を連結し、新しい文字列を返します。

String.prototype.endsWith()

文字列が searchString の文字列で終わるかどうかを判定します。

String.prototype.includes()

呼び出した文字列に searchString が含まれているかを返します。

String.prototype.indexOf()

呼び出す String オブジェクト内で、searchValue が最初に現れる位置を返します。見つからなかった場合は -1 を返します。

String.prototype.isWellFormed()

文字列に孤立サロゲートが含まれているかどうかを示す論理値を返します。

String.prototype.lastIndexOf()

呼び出した String オブジェクト内で、searchValue が最後に現れる位置を返します。見つからない場合は -1 を返します。

String.prototype.localeCompare()

参照文字列 compareString が、並べ替え順において、与えられた文字列の前になるか後になるか、あるいは、同じかどうかを示す数値を返します。

String.prototype.match()

文字列に対して正規表現 regexp を一致させるために使用されます。

String.prototype.matchAll()

regexp が一致するものすべてのイテレーターを返します。

String.prototype.normalize()

呼び出された文字列の値の Unicode 正規化形式を返します。

String.prototype.padEnd()

現在の文字列の末尾から指定された文字列で埋めた、長さ targetLength 文字の新たな文字列を返します。

String.prototype.padStart()

現在の文字列の先頭から指定した文字列で埋めた、長さ targetLength 文字の新たな文字列を作成します。

String.prototype.repeat()

オブジェクトの要素を count 回繰り返した文字列を返します。

String.prototype.replace()

searchFor が現れたところを replaceWith で置換するために使用します。searchFor は文字列または正規表現であり、replaceWith は文字列または関数です。

String.prototype.replaceAll()

searchFor が現れたところすべてを replaceWith で置換するために使用します。searchFor は文字列または正規表現であり、replaceWith は文字列または関数です。

String.prototype.search()

正規表現 regexp と呼び出された文字列が一致するところを検索します。

String.prototype.slice()

文字列の一区間を取り出し、新しい文字列を返します。

String.prototype.split()

呼び出した文字列を、部分文字列 sep が現れるところで分割し、文字列の配列を生成して返します。

String.prototype.startsWith()

呼び出した文字列が文字列 searchString で開始されているかを判断します。

String.prototype.substr() 非推奨

指定されたインデックスから、指定された文字数だけ文字列の一部を返します。

String.prototype.substring()

呼び出した文字列の指定された位置以降(または区間)にある文字が入った新しい文字列を返します。

String.prototype.toLocaleLowerCase()

文字列内の文字が、現在のロケールに沿って小文字に変換されます。

ほとんどの言語では、これは toLowerCase() と同じものを返します。

String.prototype.toLocaleUpperCase()

文字列内の文字が、現在のロケールに沿って大文字に変換されます。

ほとんどの言語では、これは toUpperCase() と同じものを返します。

String.prototype.toLowerCase()

小文字に変換された文字列の値を呼び出して返します。

String.prototype.toString()

指定されたオブジェクトの文字列を返します。Object.prototype.toString() メソッドを上書きします。

String.prototype.toUpperCase()

大文字に変換された文字列の値を呼び出して返します。

String.prototype.toWellFormed()

この文字列の孤立サロゲートをすべて Unicode 置換文字 U+FFFD に置き換えた文字列を返します。

String.prototype.trim()

文字列の先頭と末尾にあるホワイトスペースを削除します。

String.prototype.trimEnd()

文字列の末尾にあるホワイトスペースを削除します。

String.prototype.trimStart()

文字列の先頭にあるホワイトスペースを削除します。

String.prototype.valueOf()

指定されたオブジェクトのプリミティブ値を返します。Object.prototype.valueOf() メソッドを上書きします。

String.prototype[@@iterator]()

文字列値のコードポイントを反復処理し、文字列値として各コードポイントを返す、新しいイテレーターオブジェクトを返します。

HTML ラッパーメソッド

メモ: 非推奨です。これらのメソッドは避けてください。

これらはとても古い HTML 標準に基づいており、現在利用できる HTML タグや属性のサブセットしか提供していないため、使用するのには限界があります。多くが今日では非推奨または標準外のマークアップを生成します。さらに、単純な文字列の連結を検証やサニタイズなしに行うため、innerHTML を使用して直接挿入するとセキュリティ上の脅威となる可能性があります。代わりに DOM API、例えば document.createElement() など使用してください。

String.prototype.anchor() 非推奨

<a name="name">(ハイパーテキストのターゲット)

String.prototype.big() 非推奨
<big>

<blink>

String.prototype.bold() 非推奨
<b>
String.prototype.fixed() 非推奨
<tt>
String.prototype.fontcolor() 非推奨

<font color="color">

String.prototype.fontsize() 非推奨

<font size="size">

String.prototype.italics() 非推奨
<i>

<a href="url">(URL へのリンク)

String.prototype.small() 非推奨
<small>
String.prototype.strike() 非推奨
<strike>
String.prototype.sub() 非推奨
<sub>
String.prototype.sup() 非推奨
<sup>

これらのメソッドは文字列そのものが HTML タグを含むかどうかを調べないので、無効な HTML を作成する可能性があることに注意してください。

js
"</b>".bold(); // <b></b></b>

これらが行う唯一のエスケープは、属性値中の " を(anchor()fontcolor()fontsize()link()において)&quot; に置き換えることです。

js
"foo".anchor('"Hello"'); // <a name="&quot;Hello&quot;">foo</a>

文字列変換

String を使用すると、 toString() よりも信頼性の高い代替手段となり、null および undefined に対して使用することもできます。

js
const nullVar = null;
nullVar.toString(); // TypeError: nullVar is null
String(nullVar); // "null"

const undefinedVar = undefined;
undefinedVar.toString(); // TypeError: undefinedVar is undefined
String(undefinedVar); // "undefined"

仕様書

Specification
ECMAScript Language Specification
# sec-string-objects

ブラウザーの互換性

BCD tables only load in the browser

関連情報