Grammar and types

by 4 contributors:

This translation is incomplete. Please help translate this article from English.

この章では JavaScript が認識する値や、JavaScript の式の基本要素である変数、定数、リテラルについて説明します。

JavaScript は以下の値の型を認識します:

  • 数値 : 42 や 3.14159 など
  • 論理値 (真偽値) : true または false
  • 文字列 : "Howdy!" など
  • null : null 値を意味する特殊なキーワードです。null はプリミティブ値でもあります。JavaScript は大文字・小文字を区別するため、nullNullNULL などとは異なります。
  • undefined : その値が未定義であるトップレベルプロパティ。undefined はプリミティブ値でもあります。

このように値の型、すなわちデータ型の種類が比較的少ないことで、アプリケーションで便利な関数を実行することができます。整数と実数の間に明確な違いはありません。JavaScript には明確に日付を示すデータ型もありません。しかし、Date オブジェクトとそのメソッドを用いて日付を扱うことができます。

オブジェクト関数 も言語において基本的な要素です。オブジェクトは値を収める名前付きコンテナとして、関数はアプリケーションを実行可能にする手続きとして考えることができます。

データ型の変換

JavaScript は動的型付け言語です。そのため変数宣言時にデータ型を指定する必要がなく、またスクリプト実行時に必要に応じてデータ型が自動的に変換されます。例えば以下のように変数を定義したとします:

var answer = 42;

その後、同じ変数に文字列を代入できます:

answer = "Thanks for all the fish...";

JavaScript は動的型付けであるため、この代入時にエラーメッセージは出ません。

数値と文字列を + 演算子で結合する式では、JavaScript は数値を文字列に変換します。以下の式を見てみましょう:

x = "The answer is " + 42 // "The answer is 42" を返します
y = 42 + " is the answer" // "42 is the answer" を返します

それ以外の演算子がある式では、JavaScript は数値を文字列に変換しません。例えば:

"37" - 7 // 30 を返す
"37" + 7 // "377" を返す

文字列から数値への変換

数値を表す値が文字列として記憶されている場合、それを変換する手段があります。

parseInt() および parseFloat()

parseInt() および parseFloat() のページをご覧ください。

parseInt は整数のみを返しますので、小数は切り捨てられます。加えて parseInt のベストプラクティスは、常に基数のパラメータを含めることです。

+ 演算子

文字列から数値を取り出す代替手段は、+ 演算子の利用です。

"1.1" + "1.1" = "1.11.1"
(+"1.1") + (+"1.1") = 2.2   // 注: 括弧は明確さのために追加したもので、必須ではありません

変数

アプリケーションで値を識別する名前として、変数を使用します。変数の名前は識別子とも呼ばれ、あるルールに従わなくてはなりません。

JavaScript の識別子は必ずアルファベット、アンダースコア (_)、あるいはドル記号 ($) から始まらなくてはなりません。続く文字は数字 (0-9) も使用できます。JavaScript は大文字・小文字を区別するため、使用できるアルファベットは "A" から "Z" (大文字) と "a" から "z" (小文字) です。

JavaScript 1.5 より、å や ü といった ISO 8859-1 や Unicode の文字も識別子で使用できます。\uXXXX 形式の Unicode escape sequences も識別子に使用できます。

Number_hitstemp99_name が使用できる名前の例です。

変数の宣言

2 つの方法で変数を宣言できます:

  • var キーワードを用います。例えば、var x = 42 です。この構文はローカル変数およびグローバル変数どちらの宣言にも使用可能です。
  • 単に値を代入します。例えば、x = 42 です。これはいつでもグローバル変数を宣言できますが、厳格な JavaScript 警告 (strict JavaScript warning)が発生します。この方法は使用すべきではありません。

変数の評価

var 文を使用して初期値なしで宣言された変数は、undefined の値をとります。

未宣言の変数にアクセスしようとすると、ReferenceError 例外が発生します:

var a;
console.log("The value of a is " + a); // "The value of a is undefined" を出力
console.log("The value of b is " + b); // ReferenceError 例外が発生

undefined を用いて変数に値が入っているかを確認できます。以下のコードでは変数 input に値が代入されておらず、if 文での評価結果は true です。

var input;
if(input === undefined){
  doThis();
} else {
  doThat();
}

undefined は真偽値コンテキストで使用されると false として振る舞います。例えば以下のコードでは、myArray の要素が未定義であるために関数 myFunction が実行されます:

var myArray = new Array();
if (!myArray[0]) myFunction(); 

undefined は数値コンテキストで使用されると NaN に変換されます。

var a;
a + 2 = NaN

null の変数を評価すると、数値コンテキストにおいて null 値は 0 として振る舞います。また真偽値コンテキストでは false として振る舞います。例えば:

var n = null;
console.log(n * 32); // 0 を出力

変数のスコープ

変数を関数の外側で宣言すると、その変数はその文書のどのコードからも使用できるようになるため、グローバル (大域) 変数と呼ばれます。変数を関数の内部で宣言すると、その変数はその関数の中でしか使用できないため、ローカル (局所) 変数と呼ばれます。

JavaScript には ブロック文 のスコープがありません。むしろ、そのブロックを内包しているコードに対して局所化されます。例えば以下のコードでは、x のスコープは x の定義を含む関数 (あるいはグローバルコンテキスト) でありブロック、すなわち if 文ではないことから 5 を出力します。

if (true) {
  var x = 5;
}
console.log(x);

JavaScript の変数に関する独特なこととして、後に宣言される変数を例外を発生させることなく参照できるということが挙げられます。この考え方はホイスティングとして知られています。JavaScript の変数は関数や文の先頭まで、ある意味 "巻き上げ" あるいは持ち上げられます。ただし、まだ初期化されていない変数は undefined 値を返します。

/**
 * 例 1
 */
console.log(x === undefined); // "true" が記録される
var x = 3;


/**
 * 例 2
 */
// undefined 値が返ります
var myvar = "my value";

(function() {
  console.log(myvar); // undefined
  var myvar = "local value";
})();

前出の例 2 は以下と同様に解釈されます:

var myvar = "my value";

(function() {
  var myvar;
  console.log(myvar); // undefined
  myvar = "local value";
})();

ホイスティングにより、関数内にあるすべての var 文は関数内で可能な限り先頭に近い位置に置かれるでしょう。これはコードの明確さを高めるベストプラクティスです。

グローバル変数

グローバル変数は、実際にはグローバルオブジェクトのプロパティです。Web ページでのグローバルオブジェクトは window です。そのため window.variable という構文を用いてグローバル変数のセットやアクセスができます。

従ってあるウィンドウやフレームで宣言したグローバル変数は、そのウィンドウやフレームの名前を指定することで別のウィンドウやフレームからアクセスできます。例えば phoneNumber 変数を FRAMESET 文書内で宣言すると、子フレームから parent.phoneNumber としてその変数を参照できます。

定数

const キーワードを用いて、読み取り専用の名前付き定数を作成できます。定数識別子の構文は変数識別子の構文と同じです。識別子はアルファベットまたはアンダースコアから始まらなくてはならず、全体ではアルファベット、数値、アンダースコアから成るようにします。

const prefix = '212';

定数は代入によって値を変えたり、スクリプト実行中に再宣言したりすることはできません。

定数のスコープルールは、const キーワードがグローバル定数に対しても常に必須であることを除いて、変数のルールと同じです。このキーワードを省略すると、その識別子は変数を表すとみなされます。

同一スコープ内で、関数や変数と同じ名前の定数を宣言することはできません。例えば:

// この場合、エラーが発生
function f() {};
const f = 5;

// この場合もエラーが発生
function f() {
  const g = 5;
  var g;

  // 文
}

リテラル

JavaScript では値の表現にリテラルを用います。これらは固定値であり変数ではなく、スクリプト中に直接記述します。このセクションでは、以下のリテラルについて説明します:

配列リテラル

配列リテラルとは 0 個以上の式のリストであり、各々の式は配列の要素を表し、各括弧 ([]) で括られているもののことです。配列リテラルを用いて配列を作成すると、その配列は指定された値が要素として初期化され、また配列の長さは指定された引数の個数に設定されます。

以下の例では 3 つの要素を持ち、長さが 3 である配列 coffees を作成します:

var coffees = ["French Roast", "Colombian", "Kona"];

注意: 配列リテラルはオブジェクト初期化子の一種です。オブジェクト初期化子の使用を参照してください。

トップレベルのスクリプト内でリテラルを用いて配列を作成した場合、JavaScript は配列リテラルを含む式を評価するたびに配列を解釈します。さらに関数内で使用されたリテラルは、関数が呼び出されるたびに生成されます。

配列リテラルは Array オブジェクトでもあります。Array オブジェクトの詳細は Array オブジェクトをご覧ください。

配列リテラルでの余分なコンマ

配列リテラルですべての要素を指定する必要はありません。立て続けに 2 つのコンマを置くと、配列は未指定の要素を undefined として作成します。次の例では fish という配列を作成します:

var fish = ["Lion", , "Angel"];

この配列は、値を持つ要素を 2 つと空の要素を 1 つ持っています (fish[0] は "Lion"、fish[1]undefinedfish[2] は "Angel")。

要素のリストの最後にコンマをつけた場合、そのコンマは無視されます。次の例では、配列の長さは 3 です。myList[3] は存在しません。リスト内の他のコンマはすべて、新しい要素を示します。(注意: 末尾のコンマは古いブラウザでエラーを引き起こす場合がありますので、取り除くことがベストプラクティスです)

var myList = ['home', , 'school', ];

次の例では、配列の長さは 4 です。myList[0]myList[2] が抜けています。

var myList = [ , 'home', , 'school'];

次の例では、配列の長さは 4 です。myList[1]myList[3] が抜けています。最後のコンマのみが無視されます。

var myList = ['home', , 'school', , ];

自身のコードを記述する際に余分なコンマの動作を理解することは、言語としての JavaScript を理解するために重要です。欠落している要素を明示的に undefined として宣言することは、コードの明確さや保守性を高めるでしょう。

真偽値リテラル

真偽値型は 2 つのリテラル値、truefalse があります。

プリミティブな真偽値の truefalseを、Boolean オブジェクトの true や false という値を混同してはいけません。Boolean オブジェクトは、プリミティブな真偽値型のラッパです。詳細は Boolean オブジェクトを参照してください。

整数

整数は 10 進数、16 進数、8 進数で表現可能です。

  • 10 進整数リテラルは、先頭が 0 (ゼロ) ではない一連の数字で構成されます。
  • 整数リテラルにおいて先頭の 0 (ゼロ) は、それが 8 進数であることを示します。8 進整数は 0 から 7 までの数字のみで構成されます。
  • 先頭の 0x (または 0X) は、16 進数を示します。16 進整数は数字 (0 から 9) と a から f および A から F のアルファベットで構成されます。

8 進整数リテラルは廃止され、ECMA-262 第 3 版から取り除かれています (strict mode において)。JavaScript 1.5 では、依然として後方互換のためにサポートしています。

整数リテラルの例は以下のようなものです:

0、117、-345 (10 進数)
015、0001、-077 (8 進数) 
0x1123、0x00111、-0xF1A7 (16 進数)

浮動小数点数リテラル

浮動小数点数リテラルは、以下の部品で構成されます:

  • 整数部 (先頭に "+" や "-" の符号をつけてよい)
  • 小数点 (".")
  • 小数部
  • 指数部

指数部は、"e" または "E" の後に整数が続く形であり、整数の前に符号 ("+" または "-") をつけることができます浮動小数点数リテラルは少なくとも 1 つの数字と、小数点もしくは "e" (または "E") が必要です。

3.1415、-3.1E12、.1e12、2E-12 が浮動小数点数リテラルの例です。

より簡潔に書けば、次の形式になります:

[digits][.digits][(E|e)[(+|-)]digits]

例:

3.14
2345.789
.3333333333333333333

オブジェクトリテラル

オブジェクトリテラルとは、0 個以上のプロパティ名とそれに結びつけられた値の組のリストであり、波括弧 ({}) でくくられます。オブジェクトリテラルを文の先頭で使わないようにしてください。{ がブロックの始まりと解釈されるため、エラーや予期せぬ動作を引き起こすことになります。

以下にオブジェクトリテラルの例を示します。car オブジェクトの最初の要素は、myCar プロパティを定義します。2 番目の要素は、関数 (CarTypes("Honda")) を呼び出す getCar プロパティです。3 番目の要素は既存の変数 (Sales) を用いる special プロパティです。

var Sales = "Toyota";

function CarTypes(name) {
  return (name == "Honda") ?
    name :
    "Sorry, we don't sell " + name + "." ;
}

var car = { myCar: "Saturn", getCar: CarTypes("Honda"), special: Sales };

console.log(car.myCar);   // Saturn
console.log(car.getCar);  // Honda
console.log(car.special); // Toyota 

さらに、数値リテラルや文字列リテラルをプロパティ名に使用することや、オブジェクトを別のオブジェクトの入れ子にすることができます。以下の例では、これらのオプションを使用しています。

var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };

console.log(car.manyCars.b); // Jeep
console.log(car[7]); // Mazda

以下のことに注意してください:

var foo = {a: "alpha", 2: "two"};
console.log(foo.a);    // alpha
console.log(foo[2]);   // two
//console.log(foo.2);  // Error: missing ) after argument list
//console.log(foo[a]); // Error: a is not defined
console.log(foo["a"]); // alpha
console.log(foo["2"]); // two

文字列リテラル

文字列リテラルとは、0 個以上の文字を二重引用符 (") または単一引用符 (') でくくったものです。文字列は同じ種類の引用符でくくらなければなりません。つまり、どちらも単一引用符にするか、またはどちらも二重引用符にします。以下が文字列リテラルの例です:

  • "foo"
  • 'bar'
  • "1234"
  • "one line \n another line"
  • "John's cat"

文字列リテラルの値では、String オブジェクトのあらゆるメソッドを呼び出すことができます。JavaScript が自動的に文字列リテラルを一時的な String オブジェクトに変換し、メソッドを呼び出し、そして一時的な String オブジェクトを破棄します。String.length プロパティを文字列リテラルで用いることもできます:

"John's cat".length

特に String オブジェクトを使う必要がない場合は、文字列リテラルを使うようにしてください。String オブジェクトの詳細は、String オブジェクトをご覧ください。

文字列での特殊文字の使用

通常の文字に加えて、文字列では特殊文字も使用できます。次の例をご覧ください。

"one line \n another line"

ここで、JavaScript の文字列で使用できる特殊文字の表を示します。

表 2.1 JavaScript の特殊文字
文字 意味
\b 後退
\f 改ページ
\n 改行
\r 復帰
\t タブ
\v 垂直タブ
\' アポストロフィまたは単一引用符
\" 二重引用符
\\ バックスラッシュ (\)
\XXX 0 から 377 までの 3 桁の 8 進数 XXX で指定された、Latin-1 エンコーディングの文字。例えば、\251 は著作権記号を示します。
\xXX 00 から FF までの 2 桁の 16 進数 XX で指定された、Latin-1 エンコーディングの文字。例えば、\xA9 は著作権記号を示します。
\uXXXX 4 桁の 16 進数 XXXX で指定された Unicode 文字。例えば、\u00A9 は著作権記号を示します。Unicode escape sequences をご覧ください。

文字のエスケープ

表 2.1 に掲載されていない文字は直前にバックスラッシュをつけても無視されますが、この使用法は廃止されましたので使用を避けるべきです。

バックスラッシュを直前につけることで、引用符を文字列に含めることができます。これを「引用符をエスケープする」と言います。例えば:

var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
console.log(quote);

この結果は次のようになります:

He read "The Cremation of Sam McGee" by R.W. Service.

文字列にバックスラッシュそのものを含めるには、バックスラッシュのエスケープが必要です。例えば、文字列に c:\temp というファイルパスを代入するには、以下のようにします:

var home = "c:\\temp";

改行の直前にバックスラッシュを置くことで、改行をエスケープすることもできます。バックスラッシュと改行の両方が、文字列の値から取り除かれます。

var str = "this string \
is broken \
across multiple\
lines."
console.log(str);   // this string is broken across multiplelines.

JavaScript に "ヒアドキュメント" 構文はありませんが、各行の末尾に改行のエスケープ表記とエスケープした改行を置くことで似たことができます:

var poem = 
"Roses are red,\n\
Violets are blue.\n\
I'm schizophrenic,\n\
And so am I."

Unicode

Unicode は、主要な文字言語の交換や表示を目指したユニバーサルな文字コードの標準です。これは南北アメリカ、ヨーロッパ、中東、アフリカ、インド、アジア、太平洋地域の言語、さらに歴史的な文字や技術記号をカバーしています。Unicode は多言語テキストの交換、処理、表示を可能にします。また一般的な技術記号や数学記号も扱えます。国ごとの文字の標準の違いなど、多言語処理に関する国際化問題を解消することが期待されています。しかしながら、今のところ現代の文字と古い文字がすべてサポートされているわけではありません。

Unicode 文字セットはすべての有名なエンコーディングに使用できます。Unicode は ASCII (American Standard Code for Information Interchange) 文字セットをモデルにしています。これは各文字に対して数値と名前を割り当てています。文字エンコーディングは、その文字の識別情報およびその数値 (コードの位置)、さらにこの値のビット表示を指します。16 ビットの数値 (コード値) は、16 進数の値と接頭辞 U で定義されます。例えば、U+0041 は A を表します。この値に対する固有の名前は、LATIN CAPITAL LETTER A です。

JavaScript 1.3 より前のバージョンでは、Unicode をサポートしていません。

Unicode の ASCII や ISO との互換性

Unicode は ISO/IEC 10646-1; 1993 と完全互換であり、これは ISO 10646 のサブセットです。

いくつかのエンコーディング標準 (UTF-8、UTF-16、ISO UCS-2 を含む) は、Unicode を実際のビットとして物理的に表記するために使用されます。

Unicode の UTF-8 エンコーディングは ASCII 文字と互換性があり、多くのプログラムでサポートされています。Unicode 文字の最初の 128 文字は ASCII 文字に対応しており、同じバイト値をとります。Unicode 文字の U+0020 から U+007E までは、 ASCII 文字の 0x20 から 0x7E と同等です。ASCII はラテンアルファベットをサポートしており 7 ビット文字セットを使用しますが、UTF-8 は各文字について 1 オクテットから 4 オクテットを使用します ("オクテット" は 1 バイト、すなわち 8 ビット)。これにより数百万もの文字を表現できます。別のエンコーディング標準である UTF-16 は、Unicode 文字の表現に 2 オクテットを使用します。エスケープシーケンスによって、UTF-16 は Unicode の範囲全体を 4 オクテットで表現できるようになります。ISO UCS-2 (Universal Character Set) は 2 オクテットを使用します。

JavaScript および Navigator は UTF-8/Unicode をサポートしているため、非ラテン文字、国際文字、地域化された文字、そして特殊な技術記号を JavaScript プログラムで使用できます。Unicode は多言語テキストをエンコードする標準の方法を提供します。Unicode の UTF-8 エンコーディングは ASCII と互換性があるため、ASCII 文字をプログラムで使用することもできます。また、非 ASCII 文字を JavaScript のコメント、文字列リテラル、識別子、および正規表現で使用することもできます。

Unicode エスケープシーケンス

文字列リテラル、正規表現、識別子において Unicode エスケープシーケンスを使用できます。エスケープシーケンスは ASCII 文字 6 文字で構成されます。それは \u と 4 桁の 16 進数です。例えば、\u00A9 は著作権記号を表します。JavaScript ではすべての Unicode エスケープシーケンスが 1 つの文字として解釈されます。

次のコードは、著作権記号と "Netscape Communications" という文字列を返します。

var x = "\u00A9 Netscape Communications";

次の表で、よく使用される特殊文字とその Unicode 値を列挙します。

表 2.2 特殊文字に対する Unicode 値
カテゴリ Unicode 値 名前 フォーマット名
ホワイトスペースの値 \u0009 タブ <TAB>
\u000B 垂直タブ <VT>
\u000C 改ページ <FF>
\u0020 スペース <SP>
行終端の値 \u000A 改行 <LF>
\u000D 復帰 <CR>
付加的な Unicode エスケープシーケンスの値 \u0008 後退 <BS>
\u0009 水平タブ <HT>
\u0022 二重引用符 "
\u0027 単一引用符 '
\u005C バックスラッシュ \

JavaScript での Unicode エスケープシーケンスの使用方法は、Java の使用方法と異なります。JavaScript では、エスケープシーケンスが最初から特殊文字として解釈されることはありません。例えば、文字列中にある行終端のエスケープシーケンスは、関数が文字列を解釈するより前にその文字列を打ち切ることがありません。どのエスケープシーケンスをコメントで使用しても、JavaScript はそれを無視します。Java では 1 行コメント内でエスケープシーケンスが使用された場合、それを Unicode 文字として解釈します。文字列リテラルでは、Java コンパイラは最初からエスケープシーケンスを解釈します。例えば行終端のエスケープ文字 (例: \u000A) は、Java で使用すると文字列リテラルを打ち切ります。また Java では行終端が文字列リテラル内では許可されていないため、エラーが発生します。文字列リテラルで改行を表したい場合は \n を使用しなければなりません。JavaScript ではエスケープシーケンスでも \n と同じように機能します。

JavaScript ファイルにおける Unicode 文字

以前のバージョンの Gecko では、XUL から読み込まれる JavaScript ファイルは Latin-1 文字エンコーディングを前提としていました。Gecko 1.8 より、文字エンコーディングは XUL ファイルのエンコーディングから推測されます。詳しくは XUL JavaScript における国際文字を参照してください。

Unicode を用いた文字の表示

Unicode を用いることで、異なる言語の文字や技術記号を表示することができます。文字を適切に表示させるには、Mozilla Firefox や Netscape といったクライアントが Unicode をサポートしている必要があります。さらに適切な Unicode フォントもそのクライアントで使用できなくてはならず、またクライアントのプラットフォームの Unicode サポートも必要です。Unicode フォントが Unicode 文字を全部は表示できないことがよくあります。Windows 95 など、Unicode を部分的にサポートしているプラットフォームもあります。

非 ASCII 文字の入力を受け取るには、クライアントが入力を Unicode として送信する必要があります。標準的な拡張キーボードを使用すると、Unicode でサポートされている付加的な文字をクライアントが簡単には入力できなくなります。Unicode 文字を入力する唯一の方法が、Unicode エスケープシーケンスを使用することという場合もあります。

Unicode の詳細な情報については、Unicode Home Page や The Unicode Standard, Version 2.0 (出版元: Addison-Wesley、1996 年) をご覧ください。

リソース

ドキュメントのタグと貢献者

タグ: 
Contributors to this page: teoli, ethertank, akiroom, yyss
最終更新者: teoli,