JavaScript/文字列

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

JavaScriptにおいて、文字列(もじれつ、string)とは文字の連続です。 JavaScriptには内容の書き換え不能なプリミティブの文字列と、そのラッパーオブジェクトのStringオブジェクトが存在し文字列に関するプロパティとメソッドを提供します。 JavaScriptの文字列は内部的にはUTF-16で符号化されています。

最低限の知識[編集]

表示する文字列を改行したい場合[編集]

文字列に\nを挿入した位置で、改行をします。

たとえば

<script>
  alert('He\nllo World!');
</script>

をブラウザで表示すると

He
llo World!

と警告ダイアログに表示されます。

概要[編集]

文字列はJavaScriptの基本的なデータ型(プリミティブ型)の一つです。文字列は""または''引用符で囲んで表します(もう1つの書式テンプレートリテラルについては後述)。

const str = "Hello, world!";
// または
const str = 'Hello, world!';

この表記を文字列リテラル(もじれつリテラル、string literal)といいます。シングルクォートとダブルクォートに違いはありませんが、1つの文字列リテラルは同じ種類の引用符で囲まなければなりません。以下は文字列リテラルの例です。

const str0 = "Hello, world!";
const str1 = '世界よこんにちは';
const str2 = "42";
const str3 = "I'm a string.";
const str4 = 'I\'m a string.';

'I\'m a string.'"I'm a string." と等しい文字列です。シングルクォートの中にシングルクォートを書く場合は、直前にバックスラッシュ (\) を付けます。ダブルクォートの中にダブルクォートを書く場合も同様です。直前のバックスラッシュをエスケープ文字(エスケープもじ、escape character)といいます。改行などの特殊文字は通常の文字で表すことができないため、\nのようなエスケープシーケンスを使って表現します。\そのものを表す場合は、\\と書きます。

JavaScriptのエスケープシーケンスの一覧
文字 意味 ISO/IEC 8859-1エスケープシーケンス Unicodeエスケープシーケンス
\b バックスペース \x08 \u0008
\t タブ \x09 \u0009
\n 改行 \x0A \u000A
\v 垂直タブ \x0B \u000B
\f 改ページ \x0C \u000C
\r 復帰 \x0D \u000D
\" " \x22 \u0022
\' ' \x27 \u0027
\\ バックスラッシュ \x5C \u005C
\XXX ISO/IEC 8859-1エスケープシーケンス(八進法) \x00-\xFF \u0000-\u00FF
\xXX ISO/IEC 8859-1エスケープシーケンス(十六進法) \x00-\xFF \u0000-\u00FF
\uXXXX Unicodeエスケープシーケンス(十六進法) \x00-\xFF \u0000-\uFFFF

JavaScriptによる文字列の改行やタブなどのエスケープシーケンスがalertメソッドやconsole.logなど一部のメソッドでしか動作しないかのように見えます。 これはHTML文書では内容がフィリング(詰め込み)されるため改行やタブは空白と同じ効果とからです。 このため、document.writeメソッドやdocument.writelnメソッドあるいはinnerHTMLプロパティではエスケープシーケンスのが作用していることを確認できません。 ISO/IEC 8859-1エスケープ文字では\x00から\xFFまでの文字を表すことができます。Unicodeエスケープ文字では\u0000から\uFFFFまでの文字を表すことができます。 JavaScriptでは互換性のためサロゲートペアの文字列をサポートしメソッドとサポートしている構文があるので使用にあたっては注意が必要です。特に絵文字はサロゲートペアなのでサポートしている構文を使うよう心がけて下さい(String.fromCharCodeString.prototype.charCodeAtなどのメソッドはサロゲートペアに対応していませんが、スプレッド構文はサロゲートペア4バイトを正しく1文字と扱えます)。

種々雑多な知識[編集]

String[編集]

Stringオブジェクトには文字列に関するプロパティとメソッドが提供されています。

const str = new String("Hello, world!");
alert( str.length ); // "13" と警告ダイアログに表示 -- 文字列の長さ

Stringオブジェクトでは文字列に関するさまざまなメソッドが提供されている。 文字列は自動的にStringオブジェクトのインスタンスに変換されるので、文字列でメソッドを使うことが出来る(ように見える)。このようなクラスをプリミティブラッパークラスと呼びます。

プリミティブである文字列と、プリミティブラッパークラスであるStringオブジェクトは多くの場合意識しないでも問題有りませんが、いくつかの違いがあります。まず文字列は String 型ですが、 Stringオブジェクト は Object 型です。

const pstr = "Hello, world"
const strw = new String("Hello, world!");
alert( typeof pstr ); // "string"
alert( typeof strw ); // "object"

また、eval() の引数に文字列を渡した場合は文字列を評価しますが、Stringオブジェクトを渡した場合は評価せず文字列を返します。Stringオブジェクトから元の文字列を得るには valueOf() メソッドを使います。

const expr = "6 * 7";
const oexpr = new String(expr);
alert( eval(expr) ); // "42"
alert( eval(oexpr) ); // "6 * 7"
alert( eval(oexpr.valueOf()) ); // "42"

プロパティ[編集]

メソッド[編集]

文字の取得[編集]

文字列の個々の文字を取り出すには、charAtメソッドを使用します(帰ってくるのは文字、、ではなく長さ1の文字列です)。

const code = "Hello, world!".charAt(0); // "H"

文字列を配列として扱うこともできます。

const H = "Hello, world!"[0];

文字コードUTF-16)を取得するにはcharCodeAtメソッドを使用します。

alert( "Hello, world!".charCodeAt(0) ); // "72" と警告ダイアログに表示 -- "H" のバイト表現

文字列の比較[編集]

文字列は数値と同じ比較演算子を使用して比較することができますが、Unicode 値を使用し(電話帳順ではなく)標準的な辞書順に基づいて比較されます。

if ( "abc" < "abd" ) { // "abc" が "abd" より小さいならば
    alert(true);   // "true" と警告
}

部分文字列[編集]

部分文字列(ぶぶんもじれつ、substring)とは、文字列の部分のことです。JavaScriptで "Hello, world!" から "world" の部分を取り出す処理の書き方はいくつかあります。まず、文字列の個々の文字を取得する処理についておさらいしておきましょう。

H e l l o , w o r l d !
0 1 2 3 4 5 6 7 8 9 10 11 12

このように文字列の個々の文字には、インデックス (index) と呼ばれる添え字がふられています。インデックスは0から始まることに注意してください。また空白も一文字とみなすことにも注意してください。このとき、lengthプロパティで取得できる文字列の長さは13です。最後の文字のインデックスは文字列の長さより1小さくなります。charAtメソッドにインデックスを渡すと、個々の文字を取り出すことができます。

const letter = "Hello, world!".charAt(7);

"world" を取り出すにはsliceメソッドを使います。

const str = "Hello, world!".slice(7, 12);

第1引数に取り出す文字列 ("world") の最初の文字 ("w") のインデックス、第2引数に最後の文字の ("d") のインデックス + 1を渡します。第2引数は第1引数 + 部分文字列の長さと言い換えることもできます。まとめると、sliceメソッドは第1引数以上、第2引数未満の部分文字列を返します。

const world = "Hello, world!".substr(7, 5);
// および
const world = "Hello, world!".substring(7, 12);

Stringオブジェクトにはsliceメソッドのほかにも、substrメソッド、substringメソッド等があります。

ウェブコンテンツへ文字列表示[編集]

innerHTMLプロパティ使うと、JavaScript 側プログラムで用意した文字列などの変数を、HTMLとして表示することができます。 用途として、たとえば HTML入力フォームなどの結果に応じてJavaScriptのif文などの制御構造などを用いて表示したいメッセージを変更するなどが考えられる。 JavaScriptのコード内ではDIV要素やBR要素を操作するためにDOMが用意されている。 See{{DOM}}

テンプレート・リテラル[編集]

ECMAScript 2015から使えるようになった新機能として、文字列に式を組み込む「テンプレート・リテラル」があります(草案段階では「テンプレート・リテラル」(Template literals)は「テンプレート文字列」(Template strings)と呼ばれていましたが[1]、ES2015仕様書では「テンプレート・リテラル」Template literals)と呼ばれるようになりました[2][3])。

テンプレート・リテラルのプレースホルダー[編集]

従来でも、"a = " + a + ", b = " + b + ", c = " + c + ";" のような方法で変数の値を文字列に反映することは可能でしたが甚だ可読性を毀損していました[4]。 テンプレート・リテラルでは、"a = ${a}, b = ${b}, c = ${c}";" のようにバッククォート記号 `で文字列全体を囲み、式は${ }のようにドルマーク($)の先頭についた波括弧で囲み記載します。 この様にテンプレート・リテラルに埋め込まれた式をプレースホルダーと呼ばれます。

コード例

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>テンプレート・リテラルの実験</title>
  </head>
  <body>
    <p id="myTarget">JavaScriptに対応したブラウザで表示して下さい。</p>
  </body>
  <script type"text/javascript">
    const name = "タロウ";
    const sex = "男"
    const mesg = `	${name}${sex} です。` ;
    const elm = document.querySelector("#myTarget");
    elm.innerHTML = mesg ;
  </script>
</html>

結果

タロウは 男 です。

テンプレート・リテラルで複数行記載[編集]

テンプレート・リテラルは、" "' 'とは違い、複数行にまたがることが許されます。

const multi_lines = `この文字列はテンプレート・リテラルを使いました。
テンプレート・リテラルは + 演算子で複数の文字列をつなぐ必要なく、
複数行にまたがる文字列を記述できます。
他の言語の、ヒアドキュメントの様な使い方ができます。`;
console.log(multi_lines);
/*
この文字列はテンプレート・リテラルを使いました。
テンプレート・リテラルは + 演算子で複数の文字列をつなぐ必要なく、
複数行にまたがる文字列を記述できます。
他の言語の、ヒアドキュメントの様な使い方ができます。
*/

タグ付きテンプレート[編集]

テンプレート・リテラルの前に式(タグ)がある場合、タグ付きテンプレートと呼ばれます。 この場合タグ式(典型的には関数)がテンプレート・リテラルとともに呼び出され、出力する前にそのリテラルを操作することができます。

<source lang="js"> console.log`Text`; <source>

従来の文字列リテラルを拡張できなかったのか?

テンプレート・リテラルは従来の文字列リテラルに比べて多機能ですが、従来の文字列リテラルにこの機能を追加しなかったのはなぜでしょうか?

答えは、互換性です。

テンプレート・リテラルに限らず、新機能をECMAScriptに追加する場合

従来からあるスクリプトの「意味が変わったり」(意味論のは下位)、「性能が落ちて」(機能性の毀損)はいけない。

という制約があります。このため従来の文字列リテラルにはテンプレート・リテラルの新機能を付与することはできませんでした。

  1. ^ 山田祥寛『改訂新版 JavaScript 本格入門』ISBN:978-4-7741-8411-1 2016 技術評論社、初版 第6刷、53ページ
  2. ^ Template literals (Template strings)They were called "template strings" in prior editions of the ES2015 specification.
  3. ^ Standard ECMA-262 6th Edition / June 2015 ECMAScript® 2015 Language Specification::11.8.6Template Literal Lexical Components
  4. ^ ["a = ", a, ", b = ", b, ", c = ", c, ";"].join("")のように配列に文字リテラルと式を並べ join するスタイルが苦肉の策として使われることが有りました。