目次
JavaScriptには、単一のデータを保持するような単純なものから、複数のデータを格納するものまで、さまざまなデータを効率的に扱うために多様なデータ構造が提供されています。
本章ではJavaScriptのデータ構造について解説します。なお、本章では内容が豊富であるため、記事を二部に分けて詳しく説明します。
定数と変数の定義
JavaScriptを含む多くのプログラミング言語には文字や数値などのデータに名前を付け、繰り返し利用できるようにする「定数」と「変数」という機能があります。
以下はJavaScriptの定数や変数に値を割り当てる宣言方法と具体例です。
JavaScriptでは、キーワードを用いて「定数」か「変数」を宣言し、定義名に割り当てる値を指定します。定義名は開発者が自由に決めることができますが、定義名の最初に数字を付けたり、後述するJavaScriptの「キーワード」などの「予約語」は使用できません。(予約語とは、JavaScriptの言語仕様として特別な意味合いを持つ単語です。)
定数
定数は定義時に値が割り当てられた後、その後の処理でその値を変更することが出来ないことを意味します。定数の宣言には「const」というキーワードを使用し、定義名は大文字で記述することが推奨されています。
以下は定数として値を定義する際の記述例と、その出力結果となります。
■記述例(JavaScript)
const SYS_NAME = "サンプルシステム";
console.log(SYS_NAME);
なお、上記例の定数名「SYS_NAME」に新しく値を再代入しようとすると、次のようなエラーが発生します。
■間違った記述例(JavaScript)
const SYS_NAME = "サンプルシステム";
SYS_NAME = "システム名変更"; //再代入しようとするとエラーが表示されます
console.log(SYS_NAME);
変数
「変数」は定義時に値が割り当てられた後、その値が変更できることを意味します。変数を宣言するにはキーワードに「var」や「let」を使用します。これらのキーワードを使って宣言された定義名はどちらも「変数」ですが、それぞれ異なる挙動を持ちます。
以下は、「var」を使用して変数を定義する記述例とその表示結果となります。
■記述例(JavaScript)
var message = "こんにちは";//変数の定義
message = "こんばんは";//変数の再代入
console.log(message);
上記例では、1行目で宣言された変数「message」に定義された値が、2行目で「こんばんは」に再代入されるため、コンソールには「こんばんは」が表示されます。
スコープ
スコープとは、JavaScriptにおいて変数や定数が参照できる範囲を決める仕組みです。スコープは一般的にブロック(中括弧 {} で囲まれた部分)を使って分けられます。ブロック内で宣言された変数や定数は、そのブロック内でのみ有効であり、ブロックの外から参照することができません。これをローカルスコープといいます。一方、ブロックに囲まれていない範囲をグローバルスコープといい、そこで宣言された変数や定数はどこからでも参照可能です。
以下はスコープの構成図です。
なお、使用するキーワードによって、スコープの参照範囲が異なります。以下はグローバルスコープ(ブロック外)で「const」「let」キーワードを使って定数CONST_MSGと変数let_msgを定義し、これらがグローバルスコープ(ブロック外)とローカルスコープ(ブロック内)で参照できるか確認する記述例と表示結果です。
■記述例(JavaScript)
const CONST_MSG = "constで定義したメッセージです";
let let_msg = "letで定義したメッセージです";
console.log(CONST_MSG); //ブロック外で定数を参照
console.log(let_msg); //ブロック外で変数を参照
{
console.log(CONST_MSG); //ブロック内で定数を参照
console.log(let_msg); //ブロック内で変数を参照
}
上記の例では、ブロック外で宣言した定数CONST_MSGと変数let_msgの値は、ブロックの外と内のconsole.log()で表示されています。これはグローバルスコープで「const」「let」キーワードを使って定義した定数や変数は、定義された後であればどこでも参照できるためです。
続いては、定数CONST_MSG、変数let_msgをローカルスコープ内で定義した場合の記述例と表示結果です。
■記述例(JavaScript)
{
const CONST_MSG = "constで定義したメッセージです";
let let_msg = "letで定義したメッセージです";
console.log(CONST_MSG);//ブロック内で定数を参照
console.log(let_msg);//ブロック内で変数を参照
}
console.log(CONST_MSG); //ブロック外で定数を参照
console.log(let_msg);//ブロック外で変数を参照
上記の例では、ブロック内で定義された定数や変数を、同じブロック内からconsole.log()で出力した場合、割り当てられた値を確認することができますが、ブロック外から出力した場合ではエラーが表示されます。これは「const」「let」キーワードを使って、ローカルスコープで定義した定数や変数は、そのスコープ内でしか参照できないためです。
ただし、キーワードに「var」を指定した変数は特殊で、グローバルスコープで定義したものとみなされるため、その変数が定義された後であれば、ソースコード内のどこからでも参照することができます。
以下はローカルスコープで「var」キーワードを使って変数messageを定義し、ブロック外で出力した記述例と表示結果です。
■記述例(JavaScript)
{
var message = "varキーワードはグローバルスコープ扱いです";
}
console.log(message); //グローバルスコープとして扱われるため外からでも参照可能
前述の通り、「var」キーワードで定義された変数はどこからでも参照できるため、一見便利に見えるかもしれませんが、同一名の変数を再宣言してしまうと、元々の変数の値が新しい値で上書きされます。そのため予期せぬエラーや不具合の原因となる可能性があり、取り扱いには注意が必要です。
本試験では、キーワード「const」「let」「var」の特徴とスコープの参照範囲の違いについて、具体的なコード例を通して問われやすいかなと思いますので、理解を深めて試験に臨みましょう!
値の種類
定数や変数に割り当てる値には、「023」「100」などの「数値」や「こんにちは」のような「文字列」など、様々な種類がありますが、定数や変数に割り当てられたデータの種類を「データ型」と呼びます。
プログラミングでは、定数や変数に割り当てるデータ型を決めることは非常に重要です。例えば、変数に「3450」という値が割り当てられている場合について考えます。
この変数が数値「3450」である場合、四則演算などに使用しますが、単なる文字列としての数値「”3450”」として使用される場合、それは暗証番号や電話番号の一部かもしれません。そのような場合、これらの値は計算することが想定されていませんから、加算したり除算したりされては困ります。そのためプログラミングでは、使用するデータの意図に応じて適切なデータ型を選択し、予期せぬエラーや結果の誤りを防ぐことが重要です。
JavaScriptもこの点において例外ではありませんが、JavaScriptでは値を変数に割り当てる際にデータ型を自動で判別するため、型を意識する必要はほとんどありません。しかし、特定の操作においては適切なデータ型でないと動作しない場合があるため、データ型についてしっかりと理解しておく必要があります。
JavaScriptのデータ型は大きく分けて「プリミティブ型」と「オブジェクト型」の2種類があり、その中に様々なデータ型を持ちます。本章では、「プリミティブ型」について説明を行い、次の記事にて「オブジェクト型」について説明します。
プリミティブ型
概要:プリミティブ型は単一の値のみ保持し、その値自体は変更不可能です。その変数に新しい値を割り当てることは可能ですが、割り当てられた値そのものを変更することはできません。プリミティブ型は全部で7種類あり、データ型を判定するには「typeof」演算子を用います。
undefined
概要:変数や定数として宣言されていない、あるいは値が定義されていない変数をundefinedと呼びます。
以下は、値が定義されていない変数testのデータ型を判定する例です。
■記述例(JavaScript)
let test;
console.log(typeof test);
論理型(Boolean)
概要:true(真) または false(偽)のどちらかの値が割り当てられた変数のデータ型です。
以下は、trueを割り当てた変数 test1とfalseを割り当てた変数test2のデータ型を判定する例です。
■記述例(JavaScript)
let test1 = true;
let test2 = false;
console.log(typeof test1);
console.log(typeof test2);
上記例では、変数test1とtest2に直接「true」「false」を割り当てられていますが、実際には条件判定の結果として得られた真偽値を変数に割り当てて利用します。
数値型(Number)/長整数型(BigInt)
概要:数値型は数値を表すデータ型で、表現可能な数値範囲は64ビット浮動小数点形式を使用しています。詳しい説明は省略しますが、この型は整数や浮動小数点を含む、非常に大きな数値や非常に小さな数値を取り扱うことができます。これに加え、数値型には「infinity(正の無限大)」「-infinity(負の無限大)」「NaN(Not a Number:非数)」があります。また、試験には問われることは無いと思いますが、Number型で表現できないような、非常に大きな整数を取り扱う場合には長整数型(BigInt)を使用します。
以下は、数値「3.141592」が割り当てられた変数test1と、「NaN」が割り当てられた変数test2のデータ型を判定する例です。
■記述例(JavaScript)
let test1 = 3.141592;
let test2 = NaN;
console.log(typeof test1);
console.log(typeof test2);
文字列型(String)
概要:文字列型はテキストデータを表すために使用するデータ型です。
以下はテキストデータ「文字列」が割り当てられた変数testのデータ型を判定する例です。
■記述例(JavaScript)
let test = "文字列";
console.log(typeof test);
JavaScriptで文字列型を使用するには、文字列を「’(シングルクォート)」または「”(ダブルクォート)」で囲む必要があります。どちらの引用符を用いても正しく動きますが、文字列の開始と終了には、同じ引用符を使用しなければエラーとなります。
シンボル型(Symbol)
概要:シンボル型は、Symbol関数を使用する際のデータ型です。Symbol() 関数を使って宣言された定数や変数は、それぞれ独自の値を持っていて、他のどの値とも重複しません。そのため、他に影響させたくない独自の関数や、後述するオブジェクトのプロパティを参照するためのキーとして利用されます。
以下はSymbol関数「Symbol()」で生成されたシンボルを変数testに割り当て、そのデータ型を判定する例です。
■記述例(JavaScript)
let test = Symbol();
console.log(typeof test);
null型
概要:null型は意図的に値が存在しないことを表します。
以下は、nullを割り当てた変数testのデータ型とデータの値を出力した例です。
■記述例(JavaScript)
let test = null;
console.log(typeof test);
console.log(test);
上記例では、データ型には「object(オブジェクト型)」と表示されますが、これはJavaScriptの初期の設計ミスによるものであり、歴史的な理由からそのままにされています。変数testをconsole.log()を使用して出力すると、割り当てられる値はnullの一つしか持たないので、プリミティブ型の1つとなります。
冒頭で紹介した通り、JavaScriptのデータ構造については内容が豊富であるため、記事を前半部と後半部に分けて紹介を行います。前半部では、定数と変数の基本的な定義から始まり、さまざまなデータ型(プリミティブ型を含む)の種類とその特性について説明しました。後半部では「オブジェクト」と「演算子」について説明します。
それでは、今回はここまで〜。