JavaScript/字句構造
字句構造
編集プログラミング言語における字句構造(Lexical Structure)は、プログラムのテキストを構成する基本的な要素やトークンの規則的な配置を指します。字句構造はプログラムの解析の初歩であり、プログラムを理解しやすく、機械が処理しやすい形に変換します。以下は、字句構造の主な要素です:
- トークン (Tokens): プログラムの基本的な構成要素で、コンパイラやインタプリタがプログラムを解析する際に扱う最小の単位です。トークンには識別子、キーワード、演算子、リテラルなどが含まれます。
- 識別子 (Identifiers): 変数や関数、クラスなどの名前を指します。識別子は一般に文字またはアンダースコアで始まり、その後に文字、数字、アンダースコアが続きます。
- キーワード (Keywords): プログラムの構造や動作を指定するための予約語です。キーワードは通常、特別な意味を持ち、変数や関数名として使用することはできません。
- リテラル (Literals): データの値そのものを表現するための記法です。数値リテラル、文字列リテラル、真偽値リテラル、nullリテラルなどが含まれます。
- 演算子 (Operators): 値を組み合わせて新しい値を生成するための記号やキーワードです。算術演算子、比較演算子、論理演算子などがあります。
- デリミタ (Delimiters): プログラム内の構造を区切るための特殊な記号や文字です。例えば、括弧
()
、中括弧{}
、角括弧[]
などがデリミタです。 - コメント (Comments): プログラム内で説明やメモを残すためのテキストで、実行時には無視されます。コメントはソースコードの読みやすさを向上させる役割があります。
字句構造は通常、プログラムを構文解析する際に使用され、正確で一貫性のある形式でコードを書くための基礎を提供します。また、コンパイラやインタプリタは字句構造を理解してコードを適切に処理します。字句構造は言語ごとに異なりますが、多くのプログラミング言語で共通の要素が見られます。
JavaScriptの字句構造
編集JavaScriptの字句構造には、以下に挙げる主な要素が含まれます:
- トークン (Tokens): JavaScriptのプログラムはトークンに分割されます。トークンにはいくつかの種類があり、これがJavaScriptの字句構造を構成します。
- 識別子 (Identifiers): 変数や関数、クラスなどの名前を指す識別子は、文字またはアンダースコアで始まり、その後に文字、数字、アンダースコアが続きます。
const variableName = "example";
- キーワード (Keywords): JavaScriptには特定の意味を持つ予約語(キーワード)があります。例えば、
if
、else
、function
などがあります。if (condition) { // code } else { // code }
- リテラル (Literals): データの値そのものを表現するための記法です。JavaScriptの主なリテラルには数値リテラル、文字列リテラル、真偽値リテラル、nullリテラルなどがあります。
const numberLiteral = 42; const stringLiteral = "Hello, World!"; const booleanLiteral = true; const nullLiteral = null;
- 演算子 (Operators): 演算子は値を組み合わせて新しい値を生成するための記号やキーワードです。算術演算子、比較演算子、論理演算子などがあります。
const result = 10 + 5; // 算術演算子 const isEqual = (result === 15); // 比較演算子
- デリミタ (Delimiters): プログラム内の構造を区切るための特殊な記号や文字です。括弧
()
、中括弧{}
、角括弧[]
などがデリミタです。function exampleFunction() { const ary = [ 2, 3, 5, 7 ]; }
- コメント (Comments): プログラム内で説明やメモを残すためのテキストで、実行時には無視されます。コメントはソースコードの読みやすさを向上させる役割があります。
これらの要素が組み合わさり、JavaScriptのプログラムを構成します。字句構造は通常、JavaScriptエンジンがプログラムを解析する際に使用され、正確で一貫性のある形式でコードを書くための基盤となります。
Lexical grammar(字句構文)
編集JavaScriptのソーステキストは文字の連続であり、解釈器が理解するためには、文字列をより構造的な表現に解析する必要があります。解析の最初のステップは字句解析と呼ばれ、テキストは左から右にスキャンされ、個々の入力要素のシーケンスに変換されます。一部の入力要素は解釈器にとって重要でなく、このステップの後に削除されます。これには空白やコメントが含まれます。それ以外の要素(識別子、キーワード、リテラル、区切り子など)は構文解析のために使用されます。行の終端子と複数行コメントも構文的には無視されますが、自動セミコロン挿入のプロセスに影響を与え、一部の無効なトークンシーケンスが有効になります。
Format-control characters(フォーマット制御文字)
編集フォーマット制御文字には視覚的な表現がなく、テキストの解釈を制御するために使用されます。
Format-control characters(フォーマット制御文字) Code point Name Abbreviation Description U+200C Zero width non-joiner <ZWNJ> 特定の言語でリガチャに結合されないように文字の間に配置(Wikipedia)。 U+200D Zero width joiner <ZWJ> 特定の言語で通常は結合されない文字の間に配置し、文字を結合形式でレンダリング(Wikipedia)。 U+FEFF Byte order mark <BOM> スクリプトの先頭に使用され、Unicodeとテキストのバイト順序を示す(Wikipedia)。
JavaScriptのソーステキストでは、<ZWNJ>と<ZWJ>は識別子の一部として扱われ、<BOM>(テキストの先頭ではない場合はゼロ幅ノーブレークスペース<ZWNBSP>とも呼ばれます)は空白として扱われます。
White space(空白文字)
編集空白文字はソーステキストの可読性を向上させ、トークンを区切ります。これらの文字は通常、コードの機能には必要ありません。データ転送量を削減するために空白を削除するためには、しばしばミニファイケーションツールが使用されます。
White space(空白文字) Code point Name Abbreviation Description Escape sequence U+0009 Character tabulation <TAB> 水平タブ \t U+000B Line tabulation <VT> 垂直タブ \v U+000C Form feed <FF> ページ区切り制御文字(Wikipedia) \f U+0020 Space <SP> 通常のスペース U+00A0 No-break space <NBSP> 通常のスペースだが、行が分断されないポイントがない U+FEFF Zero-width no-break space <ZWNBSP> スクリプトの先頭で使用される場合、BOMマーカーは通常の空白文字と見なされます。
他のUnicodeスペース文字("Space_Separator"カテゴリなど)は、通常のスペースとして機能します。
Line terminators(行の終端子)
編集行の終端子は、プログラム内で行の終わりを示すために使用されます。行の終端子はCR(Carriage Return、U+000D)、LF(Line Feed、U+000A)、CRLF(CR + LF)のいずれかで構成されます。JavaScriptでは、これらの終端子はほとんど同等と見なされます。
Comments(コメント)
編集JavaScriptでは、コメントはプログラム内で説明やメモを残すために使用されます。コメントは実行時には無視され、コードの解釈や実行には影響を与えません。コメントは以下の2つの形式があります。
- 単一行コメント (
//
)://
から行の終わりまでがコメントとして扱われます。// これは単一行コメントです var x = 5; // コードの末尾にもコメントを追加できます
- 複数行コメント (
/* */
):/*
で始まり、*/
で終わる範囲がコメントとして扱われます。/* これは 複数行の コメントです */ var y = 10;
JSDoc
編集JSDocは、JavaScriptのコード内にドキュメンテーションコメントを記述するためのツールです。JSDocを使用することで、JavaScriptの関数やクラス、メソッドなどのドキュメンテーションを自動化し、ドキュメント生成ツールなどで出力することができます。
JSDocは、以下のような形式でコメントを記述します。
/** * ここにコメントを記述します。 */
また、関数やメソッドの引数や戻り値の型を指定することもできます。
/** * @param {string} name - 名前 * @param {number} age - 年齢 * @return {string} - メッセージ */ function sayHello(name, age) { return `こんにちは、${name}さん。あなたは${age}歳ですね。`; }
このように、JSDocを使用することで、コード内に自己完結的なドキュメンテーションを記述することができます。また、JSDocに対応したドキュメント生成ツールを使用することで、簡単に読みやすいドキュメントを生成することができます。
以下は、クラス構文を使わずに複素数クラスを作成する例です。JSDocを使用して、コードの意味を説明します。
/** * 複素数クラス * @param {number} real 実部 * @param {number} imag 虚部 */ function Complex(real, imag) { this.real = real; this.imag = imag; } /** * 複素数の加算 * @param {Complex} other 加算する複素数 * @returns {Complex} 加算結果の複素数 */ Complex.prototype.add = function(other) { return new Complex(this.real + other.real, this.imag + other.imag); }; /** * 複素数の減算 * @param {Complex} other 減算する複素数 * @returns {Complex} 減算結果の複素数 */ Complex.prototype.sub = function(other) { return new Complex(this.real - other.real, this.imag - other.imag); }; /** * 複素数の積 * @param {Complex} other 乗算する複素数 * @returns {Complex} 乗算結果の複素数 */ Complex.prototype.mul = function(other) { return new Complex(this.real * other.real - this.imag * other.imag, this.real * other.imag + this.imag * other.real); }; /** * 複素数の絶対値 * @returns {number} 複素数の絶対値 */ Complex.prototype.abs = function() { return Math.hypot(this.real, this.imag); };
このコードでは、Complexという関数を定義しています。この関数は、realとimagという2つの引数を受け取り、それらをプロパティとして持つオブジェクトを返します。また、Complexのプロトタイプに、add、sub、mul、absといったメソッドを定義しています。
それぞれのメソッドには、JSDocで説明を追加しています。例えば、addメソッドには、引数としてComplex型のオブジェクトを受け取り、戻り値としてもComplex型のオブジェクトを返すということを示す@paramと@returnsが含まれています。
このようにJSDocを使用することで、コードの意味を明確にすることができます。
Identifiers(識別子)
編集識別子は変数や関数などの名前を識別するために使用されます。識別子の名前は文字、数字、アンダースコア、またはドル記号で始めることができます。予約語は識別子として使用できません。識別子の先頭に数字は使えません。
Keywords(キーワード)
編集JavaScriptには特別な用途のために予約されたキーワードがあります。これらのキーワードはプログラムの構文において特別な役割を果たします。一部のキーワードはECMAScriptの将来のバージョンで追加されるかもしれません。
代表的なキーワード:
var
,let
,const
: 変数の宣言function
: 関数の宣言if
,else
: 条件分岐for
,while
: ループ
Reserved Words(予約語)
編集一部の単語は将来のJavaScriptバージョンで特別な役割が割り当てられる可能性があるため、予約語として指定されています。これらの単語は通常の識別子として使用できません。
例: class
, enum
, implements
, package
など
リテラル(Literals)
編集JavaScriptにはさまざまなリテラルがあります。以下は、主なリテラルの種類です。
- 数値リテラル(Numeric Literals):
- 整数リテラル:
10
,-5
,1000
など - 浮動小数点数リテラル:
3.14
,-0.5
,2.0
など - 指数表記:
5e2
(5 * 10^2),1.5e-3
(1.5 * 10^(-3)) など
- 整数リテラル:
- 文字列リテラル(String Literals):
- シングルクォートで囲まれた文字列:
'Hello, world!'
- ダブルクォートで囲まれた文字列:
"JavaScript"
- シングルクォートで囲まれた文字列:
- 真偽値リテラル(Boolean Literals):
true
: 真false
: 偽
- null リテラル:
null
: ヌルを表す特別な値
- undefined リテラル:
undefined
: 未定義を表す特別な値
- オブジェクトリテラル(Object Literals):
{}
: 空のオブジェクト{ key: value }
: プロパティが含まれるオブジェクト
var person = { name: 'John', age: 25 };
- 配列リテラル(Array Literals):
[]
: 空の配列[1, 2, 3]
: 要素が含まれる配列
var numbers = [1, 2, 3, 4, 5];
- 関数リテラル(Function Literals):
- 関数の定義
var add = function(x, y) { return x + y; };
- 正規表現リテラル(RegExp Literals):
- 正規表現パターンの定義
var pattern = /\w+/g;
これらのリテラルはJavaScriptでの値の表現に使用され、コード内で直接値を指定できます。
以上がJavaScriptの字句要素に関する概要です。これには他にもさまざまな要素がありますが、基本的な理解を提供するものとなっています。
セミコロンの自動挿入
編集JavaScriptでは、通常、文の終わりにセミコロン(;
)を記述することが期待されますが、JavaScriptエンジンはいくつかの場合において、セミコロンを自動挿入する機能があります。これは、「Automatic Semicolon Insertion (ASI)」と呼ばれます。
ASIの基本的なルールは次の通りです:
- 行末に達したとき、もしくは文が次のものの始まる位置に到達したときにセミコロンがない場合、JavaScriptエンジンはセミコロンを挿入しようとします。
- セミコロンの挿入は、次のトークンのうちのひとつが始まる場合に行われます:
- 行末
}
(閉じ中括弧))
(閉じ丸括弧)]
(閉じ角括弧)++
(インクリメント演算子)--
(デクリメント演算子)+
(単項プラス)-
(単項マイナス)~
(ビット反転演算子)!
(論理否定演算子)await
(await
式内)
例えば、以下のコードではセミコロンが自動的に挿入されます:
function add(a, b) { return a + b; } // 上記コードは実際には以下のように解釈される /* function add(a, b) { return; // セミコロンが挿入されてしまい、次の行は実行されない a + b; } */
このような挙動に注意して、意図したコードの記述を心掛けると良いでしょう。一般的には、セミコロンを明示的に記述することが推奨されます。