文字列は、JavaScriptの文字の不変シーケンスです。各文字は16ビットのUTF-16コードユニットです。つまり、単一のUnicode文字は、1つまたは2つのJavaScript文字で表されます。文字を数えたり、文字列を分割したりする場合に、2文字の場合を考慮する必要があります(第24章を参照)。
単一引用符と二重引用符の両方を使用して、文字列リテラルを区切ることができます。
'He said: "Hello"'
"He said: \"Hello\""
'Everyone\'s a winner'
"Everyone's a winner"
したがって、どちらの種類の引用符も自由に使用できます。ただし、いくつかの考慮事項があります。
一貫して引用符を使用すると、コードが見やすくなります。ただし、異なる引用符を使用することでエスケープを回避できる場合があり、一貫性をそれほど重視しなくても済む場合があります(たとえば、通常は単一引用符を使用しますが、上記の最後の例を書くために一時的に二重引用符に切り替える場合があります)。
文字列リテラルのほとんどの文字は、単にそれ自体を表します。バックスラッシュはエスケープに使用され、いくつかの特別な機能を有効にします。
行末(行末文字、行ターミネータ)をバックスラッシュでエスケープすることにより、文字列を複数行に展開できます。
var
str
=
'written \
over \
multiple \
lines'
;
console
.
log
(
str
===
'written over multiple lines'
);
// true
var
str
=
'written '
+
'over '
+
'multiple '
+
'lines'
;
\b
はバックスペース、\f
はフォームフィード、\n
は改行、\r
は復帰、\t
は水平タブ、\v
は垂直タブです。それ自体を表すエスケープされた文字:\'
は単一引用符、\"
は二重引用符、\\
はバックスラッシュです。b f n r t v x u
と10進数字以外のすべての文字もそれ自体を表します。次に2つの例を示します。
> '\"' '"' > '\q' 'q'
\0
で表されます。
\xHH
(HH
は2つの16進数字)は、ASCIIコードを介して文字を指定します。例えば:
> '\x4D' 'M'
\uHHHH
(HHHH
は4つの16進数字)は、UTF-16コードユニットを指定します(第24章を参照)。次に2つの例を示します。
> '\u004D' 'M' > '\u03C0' 'π'
文字列のn番目の文字を返す操作は2つあります。[16] JavaScriptには文字用の特別なデータ型がないことに注意してください。これらの操作は文字列を返します。
> 'abc'.charAt(1) 'b' > 'abc'[1] 'b'
一部の古いブラウザでは、角括弧による文字への配列のようなアクセスはサポートされていません。
値は次のように文字列に変換されます。
値 | 結果 |
|
|
|
|
真偽値 |
|
| |
数値 | 文字列としての数値(例: |
文字列 | 入力と同じ(変換するものがない) |
オブジェクト |
|
任意の値を文字列に変換する最も一般的な3つの方法は次のとおりです。
| (コンストラクターとしてではなく、関数として呼び出されます) |
| |
| ( |
より記述的なので、String()
の方が好きです。次にいくつかの例を示します。
> String(false) 'false' > String(7.35) '7.35' > String({ first: 'John', last: 'Doe' }) '[object Object]' > String([ 'a', 'b', 'c' ]) 'a,b,c'
データを表示する場合、JSON.stringify()
(JSON.stringify(value, replacer?, space?))の方が標準の文字列変換よりも効果的な場合があります。
> console.log(JSON.stringify({ first: 'John', last: 'Doe' })) {"first":"John","last":"Doe"} > console.log(JSON.stringify([ 'a', 'b', 'c' ])) ["a","b","c"]
当然のことながら、JSON.stringify()
の制限事項に注意する必要があります。すべてが表示されるわけではありません。たとえば、処理できない値(関数など)のプロパティは非表示になります。プラス面としては、その出力はeval()
によって解析でき、深くネストされたデータをきれいにフォーマットされたツリーとして表示できます。
JavaScriptが自動的に変換を行う頻度を考えると、変換が常に可逆的ではないのは残念です。特に真偽値に関しては:
> String(false) 'false' > Boolean('false') true
undefined
とnull
についても、同様の問題が発生します。
文字列を比較するには2つの方法があります。まず、比較演算子を使用できます:<
、>
、===
、<=
、>=
。これらには次の欠点があります。
大文字と小文字が区別されます
> 'B' > 'A' // ok true > 'B' > 'a' // should be true false
ウムラウトとアクセントがうまく処理されません
> 'ä' < 'b' // should be true false > 'é' < 'f' // should be true false
2つ目に、String.prototype.localeCompare(other)
を使用できます。これはより良い結果をもたらす傾向がありますが、常にサポートされているわけではありません(検索と比較を参照して詳細を確認してください)。 Firefoxのコンソールでの操作例を以下に示します。
> 'B'.localeCompare('A') 2 > 'B'.localeCompare('a') 2 > 'ä'.localeCompare('b') -2 > 'é'.localeCompare('f') -2
結果が0未満の場合、レシーバーは引数よりも「小さい」ことを意味します。結果が0より大きい場合、レシーバーは引数よりも「大きい」ことを意味します。
演算子+
は、オペランドの1つが文字列になるとすぐに文字列連結を実行します。文字列の断片を変数に収集する場合は、複合代入演算子+=
が便利です。
> var str = ''; > str += 'Say hello '; > str += 7; > str += ' times fast!'; > str 'Say hello 7 times fast!'
前のアプローチでは、str
に断片が追加されるたびに新しい文字列が作成されるように見える場合があります。古いJavaScriptエンジンはこの方法で実行するため、最初にすべての断片を配列に収集し、最後に結合することで、文字列連結のパフォーマンスを向上させることができます。
> var arr = []; > arr.push('Say hello '); > arr.push(7); > arr.push(' times fast'); > arr.join('') 'Say hello 7 times fast'
ただし、新しいエンジンは+
を介した文字列連結を最適化し、内部で同様の方法を使用します。したがって、これらのエンジンではプラス演算子の方が高速です。
関数String
は、2つの方法で呼び出すことができます。
String(value)
通常の関数として、value
をプリミティブ文字列に変換します(文字列への変換を参照)。
> String(123) '123' > typeof String('abc') // no change 'string'
new String(str)
コンストラクターとして、String
の新しいインスタンス(プリミティブのラッパーオブジェクトを参照)を作成します。これは、str
をラップするオブジェクトです(文字列以外は文字列に強制されます)。例えば
> typeof new String('abc') 'object'
前者の呼び出しが一般的です。
String.fromCharCode(codeUnit1, codeUnit2, ...)
は、文字が16ビット符号なし整数codeUnit1
、codeUnit2
などで指定されたUTF-16コードユニットである文字列を生成します。例えば:
> String.fromCharCode(97, 98, 99) 'abc'
数値の配列を文字列に変換する場合は、apply()
(func.apply(thisValue, argArray)を参照)を使用して行うことができます。
> String.fromCharCode.apply(null, [97, 98, 99]) 'abc'
String.fromCharCode()
の逆はString.prototype.charCodeAt()
です。
プリミティブ文字列のすべてのメソッドは、String.prototype
に格納されます(プリミティブはラッパーからメソッドを借用するを参照)。次に、String
のインスタンスではなく、プリミティブ文字列でどのように機能するかを説明します。
次のメソッドは、レシーバーから部分文字列を抽出します。
String.prototype.charAt(pos)
位置pos
にある文字を含む文字列を返します。例えば:
> 'abc'.charAt(1) 'b'
次の2つの式は同じ結果を返しますが、一部の古いJavaScriptエンジンは文字にアクセスするためにcharAt()
のみをサポートしています。
str
.
charAt
(
n
)
str
[
n
]
String.prototype.charCodeAt(pos)
位置pos
にあるJavaScript文字(UTF-16コードユニット、第24章を参照)のコード(16ビット符号なし整数)を返します。
> 'abc'.split('').map(function (x) { return x.charCodeAt(0) }) [ 97, 98, 99 ]
charCodeAt()
の逆はString.fromCharCode()
です。
String.prototype.slice(start, end?)
位置start
から位置end
まで(end
は含まない)の部分文字列を返します。2つのパラメーターはどちらも負の値にすることができ、その場合、文字列のlength
がそれらに追加されます。
> 'abc'.slice(2) 'c' > 'abc'.slice(1, 2) 'b' > 'abc'.slice(-2) 'bc'
String.prototype.substring(start, end?)
slice()
に似ていますが、負の位置を処理でき、ブラウザ間でより一貫性のある実装になっているため、slice()
を優先して使用することをお勧めします。String.prototype.split(separator?, limit?)
separator
で区切られたレシーバーの部分文字列を抽出し、それらを配列で返します。このメソッドには2つのパラメーターがあります。
separator
:文字列または正規表現。指定しない場合、文字列全体が配列にラップされて返されます。limit
:指定した場合、返される配列には最大limit
個の要素が含まれます。次にいくつかの例を示します。
> 'a, b,c, d'.split(',') // string [ 'a', ' b', 'c', ' d' ] > 'a, b,c, d'.split(/,/) // simple regular expression [ 'a', ' b', 'c', ' d' ] > 'a, b,c, d'.split(/, */) // more complex regular expression [ 'a', 'b', 'c', 'd' ] > 'a, b,c, d'.split(/, */, 2) // setting a limit [ 'a', 'b' ] > 'test'.split() // no separator provided [ 'test' ]
グループがある場合、一致も配列要素として返されます。
> 'a, b , '.split(/(,)/) [ 'a', ',', ' b ', ',', ' ' ] > 'a, b , '.split(/ *(,) */) [ 'a', ',', 'b', ',', '' ]
文字列の文字を含む配列を生成するには、''
(空の文字列)を区切り文字として使用します。
> 'abc'.split('') [ 'a', 'b', 'c' ]
前のセクションは部分文字列の抽出についてでしたが、このセクションでは、与えられた文字列を新しい文字列に変換する方法について説明します。 これらのメソッドは、通常、次のように使用されます。
var
str
=
str
.
trim
();
つまり、元の文字列は(非破壊的に)変換された後に破棄されます。
String.prototype.trim()
文字列の先頭と末尾からすべての空白文字を削除します。
> '\r\nabc \t'.trim() 'abc'
String.prototype.concat(str1?, str2?, ...)
レシーバーと`str1`、`str2`などを連結したものを返します。
> 'hello'.concat(' ', 'world', '!') 'hello world!'
String.prototype.toLowerCase()
元の文字列のすべての文字を小文字に変換した新しい文字列を作成します。
> 'MJÖLNIR'.toLowerCase() 'mjölnir'
String.prototype.toLocaleLowerCase()
String.prototype.toUpperCase()
元の文字列のすべての文字を大文字に変換した新しい文字列を作成します。
> 'mjölnir'.toUpperCase() 'MJÖLNIR'
String.prototype.toLocaleUpperCase()
以下のメソッドは、文字列の検索と比較に使用されます。
String.prototype.indexOf(searchString, position?)
`position`(デフォルトは0)から始まる`searchString`を検索します。 `searchString`が見つかった位置を返します。見つからない場合は-1を返します。
> 'aXaX'.indexOf('X') 1 > 'aXaX'.indexOf('X', 2) 3
文字列内のテキストを見つける場合、正規表現も同様に機能することに注意してください。たとえば、次の2つの式は同等です。
str
.
indexOf
(
'abc'
)
>=
0
/
abc
/
.
test
(
str
)
String.prototype.lastIndexOf(searchString, position?)
`position`(デフォルトは末尾)から開始して、`searchString`を逆方向に検索します。 `searchString`が見つかった位置、または見つからない場合は-1を返します。
> 'aXaX'.lastIndexOf('X') 3 > 'aXaX'.lastIndexOf('X', 2) 1
String.prototype.localeCompare(other)
文字列と`other`をロケールに依存した比較を実行します。次の数値を返します。
例えば
> 'apple'.localeCompare('banana') -2 > 'apple'.localeCompare('apple') 0
すべてのJavaScriptエンジンがこのメソッドを正しく実装しているわけではありません。比較演算子に基づいているものもあります。ただし、ECMAScript Internationalization API(ECMAScript国際化APIを参照)は、Unicodeを認識した実装を提供しています。つまり、そのAPIがエンジンで利用可能な場合、`localeCompare()`は機能します。
サポートされている場合、`localeCompare()`は比較演算子よりも文字列を比較するのに適しています。詳細については、文字列の比較を参照してください。
以下のメソッドは正規表現で動作します。
レシーバー内で`regexp`が一致する最初のインデックスを返します(一致しない場合は-1)。
> '-yy-xxx-y-'.search(/x+/) 4
レシーバーに対して指定された正規表現を照合します。 `regexp`のフラグ`/g`が設定されていない場合、最初の一致に対して一致オブジェクトを返します。
> '-abb--aaab-'.match(/(a+)b/) [ 'ab', 'a', index: 1, input: '-abb--aaab-' ]
フラグ`/g`が設定されている場合、すべての一致(グループ0)が配列で返されます。
> '-abb--aaab-'.match(/(a+)b/g) [ 'ab', 'aaab' ]
`search`を検索し、`replacement`で置き換えます。 `search`は文字列または正規表現にすることができ、`replacement`は文字列または関数にすることができます。フラグ`/g`が設定された正規表現を`search`として使用しない限り、最初に出現したものだけが置き換えられます。
> 'iixxxixx'.replace('i', 'o') 'oixxxixx' > 'iixxxixx'.replace(/i/, 'o') 'oixxxixx' > 'iixxxixx'.replace(/i/g, 'o') 'ooxxxoxx'
置換文字列内のドル記号(`$`)を使用すると、完全一致またはキャプチャされたグループを参照できます。
> 'iixxxixx'.replace(/i+/g, '($&)') // complete match '(ii)xxx(i)xx' > 'iixxxixx'.replace(/(i+)/g, '($1)') // group 1 '(ii)xxx(i)xx'
関数を使用して置換を計算することもできます。
> function repl(all) { return '('+all.toUpperCase()+')' } > 'axbbyyxaa'.replace(/a+|b+/g, repl) '(A)x(BB)yyx(AA)'