deve.K

エンジニアが未来を切り開く。

JavaScript 入門 変数と定数

当ブログでは将来的にReactプログラマの開発者を目指す方に目的としたJavaScriptの基礎になります。

本日はJavaScriptの変数と定数について学習します。

変数・定数の概念・スコープについて解説致します。

javascriptの変数と定数 入門

JavaScript 変数

変数はJavaScript固有のものではございません。

実際、ほとんどすべてのプログラミング言語には変数の概念があります。

データを非常に簡単に処理および保存できます。

これはプログラムの実行中に使用できる値を格納するために使用されるオブジェクト(または名前付きメモリスペース)となります。

つまりJavaScript変数は単に保管場所の名前という事になります。

JavaScriptの変数は、他のプログラミング言語と同様に、名前、値、およびメモリアドレスを持っております。

変数の名前は変数を一意に識別します。

値は、変数に格納されているデータを参照します。

変数に格納されている値は動的であり、プログラムの実行中にいつでも変更できます。

変数は単なる名前付きのメモリ位置です、変数に対して実行されるすべての操作は、そのメモリ位置に直接影響します。

そしてすべての変数は、使用する前に宣言する必要があります。

変数の宣言

変数を作成するときは、それを宣言する必要があります。

この名前で変数を表現すると伝えてあげます。

JavaScriptでは、varまたはletキーワードを使用して変数を宣言します。

var x;

let y;

javascriptの変数

var variable_name;

// or

let variable_name;

複数の変数を宣言する必要がある場合は、次のように行うことができます。

let x, y, z;

これらのキーワードの間にはいくつかの違いがあります。

var

古いバージョンのJavaScriptで使用されております。 関数スコープとなります、これについては後に解説致します。

JavaScriptのすべてのバージョンで使用できます。

ですが現在は、非推奨となっておりますのでご注意下さい。

let

ES6(ES2015)以降での変数を宣言する新しい方法です。

ブロックスコープとなります、こちらも後に解説致します。

JavaScript変数を宣言する際には、いくつかのルールがあります。

変数名にスペースを含めることはできません。

名前には文字(aからzまたはAからZ)、アンダースコア(_)またはドル($)記号で始まる必要があります。

let a = 'hello';

let _a = 'hello';

let $a = 'hello';

名前の最初の文字の後に任意の数字[0-9]を使用できます。

JavaScript変数では大文字と小文字が区別されております。

例えば、aとAは異なる変数となります。

let a = "hello";
let A = 10;

console.log(a); // hello
console.log(A); // 10

JavaScriptの変数名または識別子として予約語を使用することはできません。

let new = 5; // Error! newはキーワードです。

予約語というのは元々JavaScriptに存在する単語となります例えばifやforなどとなります。

JavaScriptにはif構文やfor文があります。

これら予約語はコードで使用はできません。

変数名には任意の名前を付けることができますが、わかりやすい変数名を付けることをお勧め致します。

リンゴの数を格納するために変数を使用している場合は、numberOfApplesなど。

変数の命名規則

JavaScriptでは、変数名が複数の単語を含む場合、通常、変数名はキャメルケースで記述されます。

camelCase(キャメルケース)は、フレーズの途中にある各単語または略語が大文字で始まり、間にスペースや句読点がないようにフレーズを書く方法となります。

let variableName;

//大文字は2番目の単語の先頭にのみ表示

変数の命名規則にはキャメルケース、パスカルケース、スネークケースとあり、現代のプログラミング言語で最も一般的な3つの命名規則となっております。

snake_case(スネークケース)はアンダースコアケースとも呼ばれたりします。

単語のすべての文字が小文字であるか、またはアンダースコアで区切られている場合となります。

let variable_name;

JavaJavaScript、TypeScriptの言語ではスネークケースを使用することはあまりありません。

なぜかは定数を示すために使用される為です。

PascalCase(パスカルケース)はキャメルケースの命名規則に従いますが、最初の文字を大文字にします。

let VariableName;

なぜこのような規則を使用するのかは、コードベースに一貫性がもたらされ、保守が容易になる為です。

命名規則は言語によって異なります。

各言語には、プログラミングトークンの使用を指定する独自の命名規則が存在します。

それでは変数を宣言し値を割り当てる(値を代入するとも言います)、簡単な例を見てみましょう。

変数の割り当て(代入)

javascriptの変数の代入

let myVariable; //変数の宣言

let myVariable = 10 ; //値を割り当てる

console.log(myVariable) //10が出力

変数への書き込みは、値の割り当てとも呼ばれます。

一般的に、これは等号(=)の左側に変数を配置することによって行われます。

(=)は代入演算子となります。

つまり左側には値を受け取る変数があり、右側には割り当てたい値があります。

前述で複数の変数宣言する場合の紹介しましたが、その変数に値を割り当て1つのキーワードで変数を宣言することができます。

let x, y, z;

//値の代入

let x = 5, y = 6, z = 7;

JavaScriptで複数の変数を宣言/定義するには、さまざまな方法があります。

他には

let [name,age,income] = ["Taro",20,800]

変数はconsole.log()に応じて変数で使用または保存されている情報またはデータに関するユーザーにアクセスを許可します。

数式などの計算結果などをコンソールにアウトプットする機能という事です。

console.log(name); // "Taro"

console.log(age); // 20

console.log(income); // 800

console.log()の括弧の中に変数を渡して出力します。

変数だけではなく、関数やさまざまなパラメータをコンソールに出力可能です。

console.log(2 + 3); // 5

console.log("test"); //文字列のtest

これはブラウザの開発ツールのコンソールを開き実行結果を確認できます。

変数の値を変更(再代入)

変数に格納されている値を変更することができます。

// 5は変数xに割り当てられます

let x = 5; 

console.log(x); // 5

//変数xの値が変更されます
x = 2; 

console.log(x); // 2

何かしらのエラー、テキストが赤く表示されている場合は良くエラー文を読む事です。

例えば、『SyntaxError』という単語が表示されているのであれば、プログラムの文法や構文が正しくない場合に警告されるエラーですので、どこかしらで書き間違えがあります。

値の型操作

変数にいくつかの値の型がございます。

変数は他の型の情報も格納できます。

変数の型は、変数が保持するデータの型に基づいています、さまざまな型を見てみましょう。

文字列(string)

テキストの一部を表します。

値を引用符で囲む必要がありますダブルクォーテーション(例"This is a value.")またはシングルクォーテーション(例'This is a value')で囲みます。

数値(Number)

数値は、数学演算を実行できる数値を表します。

数字を書くだけで、小数点以下の桁数(ある場合)を区切るには、ドット(1または23.044)を使用します。

ブール値(boolean)

ブール値はフラグを表し、ステータスはtrueまたはnotのいずれかになります、実際使用できる値は、trueおよびfalseの2つだけです。

null

値がないことを示す特殊な型となります。

nullによる参照が持つ意味は、実装言語によって様々であり異なりますので注意して下さい。

undefined

変数が存在しないことを示す特殊な型です。

NaN (Not a Number)

数値が予期されていたために操作が失敗したが、別の型が見つかったことを示す特別な型です。

計算エラーを表します。

上記のさまざまなな型は、Primitive(プリミティブ値またはプリミティブデータ型)です。

これらを踏まえてJavaScriptには強い型はありません。

文字列を含む変数に後で数値を含めることができることを意味します。

したがって宣言では、変数に特定の型の値のみを含めるように強制をしているわけではありません。

var a;

a = 5 + 5; // 10

a = "string1" + "string2" ; // "string1string2"

a = "a" + 5; // a5

a = "1" + 5; // 15、『1』は文字列です、なので数学を実行できません

a = 4 * 4 ; // 16

a = "a" * 4 ; // NaN

a = "4" * 4 ; // 16、最初の文字列を自動的に変換します

再宣言

まず、varキーワードを使用して変数を2回宣言してもエラーは発生しません。

var x = 2;

var x = 5;

しかしletキーワードの場合、エラーが発生します。

let x = 2;

let x = 5;

//TypeError:識別子xはすでに宣言されています。

ただし、letで宣言された変数は、ネストされたブロックで再利用可能です(再宣言はされません)。

let x = 5;    

{
   let x = 6;
   console.log(x); // >> 6
}

console.log(x); // >> 5

それでは変数スコープについて学びましょう。

スコープとは何なのか?少し概要を説明致します。

スコープは変数の有効な範囲となりアクセス可能性を決定します。

つまり、『変数のスコープ』は、プログラム全体で変数を使用できる場合と使用できない場合を決定します。

JavaScriptでは、変数のスコープは変数宣言の場所によって制御され、特定の変数にアクセスできるプログラムの部分を定義します。

それぞれアプリケーションの要件に応じて使用できます。

JavaScriptにはさまざまなスコープがあります。

関数スコープ

ブロックスコープ

グローバルスコープ

ローカルスコープ

関数スコープ

JavaScriptには関数スコープがあります、各関数は新しいスコープを作成します。

関数内で定義された変数は、関数外からアクセスできません。

varで宣言された変数は、関数内で宣言された場合let とconstに非常によく似ています。

それらはすべて関数スコープを持っています。

つまり関数内で使用する場合、var、let、およびconstは同様に機能します。

関数が分からない場合は今は飛ばしてもらって構いません。

ですが、これらは非常に重要なので関数の理解が深まった後に関数スコープも再度学習下さい。

function myFunction() {
var carName = "BMW";   // 関数スコープ
}
function myFunction() {
let carName = "Benz";   // 関数スコープ
}
function myFunction() {
const carName = "Volvo";   // 関数スコープ
}

ブロックスコープ

2015年にES6(ECMAScript 6)を導入する前は、JavaScriptにはグローバルスコープとローカルスコープの2種類のスコープしかありませんでした。

letおよびconstキーワードの導入により、JavaScriptに新しいタイプのスコープが追加されました。

これは特定のブロック({}で表される)内で宣言された変数に、ブロック外からアクセスすることはできません。

{

let x = "Hello, Welcome.";

console.log(x) //アクセス可能
}

console.log(x) //error

関数およびブロックのスコープは入れ子にすることができます。

{
  //  block scope
}

そのような状況では、複数のネストされたスコープを使用して、変数はそれ自体のスコープ内または内部スコープからアクセスできます。

しかし、そのスコープ外では変数にアクセスできません。

コードブロック例えばifおよびforなどは、letやconstキーワードで宣言された変数にのみスコープを定義します。

varキーワードは関数スコープに限定されます。

つまり、新しいスコープは関数内部でしか作れないということです。

そのためletまたはconstキーワードを使用できます。

JavaScriptローカルスコープ

ローカルスコープの変数は、宣言されている関数内でのみ表示されます。

JavaScriptで記述された各関数は新しいローカルスコープを作成し、このスコープで宣言されたすべての変数はローカル変数です。

function abc() {  

let x = 10; //ローカル変数

}  

簡単に言うと、ローカル変数のスコープはコードブロックまたは関数本体内で宣言および定義された場合、波括弧{ }の開始と終了の間にあります。

ブロックスコープと混同しているかもしれません。

ブロックスコープ内で宣言された変数は、ローカル変数と同等です。

これらは、定義されているブロック内で使用できます。

ブロックスコープとの違いを明確にしたいですか?

ローカルスコープとブロックスコープの主な違いは、ブロックステートメント (if条件やforループetc)が新しいスコープを作成しないことです。

//ブロックif文は新しいスコープを作成する事はありません。

if(true) {  
var apple = "りんご"; // グローバルスコープ

let banana = "バナナ";

const grape = "ぶどう";
}  

console.log(apple); // りんご

console.log(banana); //ReferenceError

console.log(grape); //ReferenceError

ローカルスコープは、同じ名前の変数を異なる関数で使用できます。

ただし、スコープ外のローカル変数を参照しようとすると、参照エラーが発生します。

ES6以降では、ローカル変数を宣言するときにletキーワードを使用することをお勧めします。

JavaScriptグローバル変数

JavaScriptグローバル変数は、スクリプト内の任意の場所で宣言され、完全なスクリプト実行のスコープを持つ変数となります、またはウィンドウオブジェクトで宣言された変数は、グローバル変数と呼ばれます。

グローバル変数は、ブロックまたは関数内で宣言されていませんが、関数またはコードのブロックで使用できます。

var data = 200;//グローバル変数

function a(){  

document.writeln(data);
  
}  

function b(){  
document.writeln(data);  
}  

a();//関数の呼び出し
b();  

グローバル変数の場合プログラム全体で有効となります、どこでどのように参照されているのかまたは更新されてるのかよく分からない現象が頻繁に多発します。

ですのでグローバル変数の使用はなるべく最小限に抑えるように心掛けて下さい。

スコープは、名前の衝突を回避するのに役立ちます。

たとえば、プログラム内の別の場所で別の目的のために同じ変数名を使用する必要がある場合や、チームの他の誰かが既にグローバルスコープで変数を宣言しており、その境界を特定したい場合を想像してください。

変数にアクセスできる範囲を明確にすると、その境界を特定しやすくなり、同じ変数にそれ以上の値を割り当てることを避け、値を変更せずにコード内の複数の場所で同じ変数名を使用できます。

定数

ES6は、constと呼ばれるキーワードを使用して定数を宣言する新しい方法を提供します。

constは、読み取り専用の参照を持つ定数を作成します。

これは変数の名前を再割り当てしようとするのを防ぐだけですが、オブジェクトは参照渡しであるため、オブジェクトプロパティを渡すことができます、後ほど解説します。

constは、プログラム全体でその変数の値を変更したくない場合に変数を宣言するためのもう1つのキーワードと思って下さい。

全体として、定数は大文字を使用するか小文字を使用するかにかかわらず宣言が可能です。

最もよく使用される一般的な規則は、すべて大文字となります。

const CONSTANT_NAME = value;

letキーワードと同様に、このconstキーワードはブロックスコープ変数を宣言します。

したがって、ブロック内で定義された変数は、外部の変数とは異なる値を表します。

注意しなければいけない点は前述した通り、constキーワードで宣言されたブロックスコープの変数は再割り当てできません。

letの場合はいつでも値を変更可能です。

let a = 10;

a = 20; //再代入

a = a + 10;

console.log(a); // 30

ただし、constキーワードによって作成された変数は『不変』です。

つまり、それらを別の値に再割り当てすることはできません。

constキーワードで宣言された変数を再割り当てしようとすると、次のTypeErrorになります。

const RATE = 0.1;

RATE = 0.2; // TypeError

//別の例

const x = 5;

x = 10;  //Error! 定数は変更できません

console.log(x)

割り当ては失敗し、定数は元の値のままとなります。

つまり定数は値を変更できない変数の一種という事です。

変数の巻き上げ

JavaScriptでの変数の巻き上げは、すべての関数または変数の先頭に移動することを意味します。

console.log(test);   // undefined

var test;
var test;
console.log(test); // undefined

エラーがスローされる事はありません。

testは宣言されているだけで値はありませんundefinedの値が割り当てられます。

下記は巻き上げる前の関数宣言です。

function func() 
{

  data = 1;
  console.log(data);  //出力 1

  var data;

}
 
func();

では巻き上げます。

function func() 
{
  var data; //トップに移動 

  data = 1;
  console.log(data);  //出力1

}
 
func();

巻き上げでは、宣言がプログラム内で上に移動したように見えますが、実際に発生するのはコンパイル段階で関数と変数の宣言がメモリに追加されることです。

JavaScriptでの巻き上げの概念により、変数と関数を宣言する前に使用できるという事になります。

ですが、letおよびconstキーワードの場合、varとは異なった挙動をします。

console.log(x) //ReferenceError

let x = 1

console.log(a) //ReferenceError

const a = 1;

つまり、letおよびconstで巻き上げた場合undefinedではありません。

これは可変巻き上げと呼ばれます。

この概念はJavaScript特有の概念となります。

JavaScriptでは関数宣言と変数宣言は初期化ではなく、引き上げられるだけであることに注意してください。

開発者が巻き上げを理解していない場合、プログラムにバグ(エラー)が含まれている可能性があります。

巻き上げについては下記で詳しく解説しております。

dev-k.hatenablog.com

JavaScriptの定数とオブジェクト

constキーワードは、作成する変数が読み取り専用であることを保証しますが、const変数参照が不変である実際の値を意味するものではありません。

例えば、変数は定数ですがpersonプロパティの値を変更ができます。

const person = { 

age: 20 

};

person.age = 30; //変更可能

console.log(person.age); // 30

注意点は定数に別の値を再割り当てすることはできません。

person = { 

age: 50  // TypeError

};

オブジェクトの値を不変にし、プロパティの値の再割り当てを不可能にする場合はメソッドを使用します。

Object.freeze()メソッドになります。

これはオブジェクトを凍結させ、凍結されたオブジェクトは変更できなくなります。

const person = Object.freeze({

age: 20

});

person.age = 30; // TypeError

このメソッドを使用する場合は勘違いしてはいけのが プロパティによって参照されるオブジェクトではなく、オブジェクトのプロパティをフリーズする可能性があります。

一定で凍結されているので、プロパティの追加などは可能となります。

変数・定数それらの違いまとめ

JavaScriptには、変数を宣言するための3つの異なるキーワードがあるのを学んだかと思います。

これら3つの違いは、スコープ、巻き上げ、および再割り当てに基づいております。

キーワード 範囲 巻き上げ 再代入 再宣言
var 関数スコープ 可能 可能 可能
let ブロックスコープ 不可 可能 不可
const ブロックスコープ 不可 不可 不可

一般的に受け入れられている方法は、ループや再割り当ての場合にletを活用し、変数の値がプログラム全体で変更されないことが確実な場合は、可能な限りconstを使用することをお勧めします。

ただしconstではサポートしていないブラウザがいくつかあります、それら詳細についてはJavaScriptブラウザサポートにアクセスしご確認下さい。

const | Can I use... Support tables for HTML5, CSS3, etc

本日は以上となります。

当記事ではJavaScript変数・定数の概念と、ローカル変数とグローバル変数、及びスコープの種類について学習しました。

最後まで読んで頂きありがとうございます。

プライバシーポリシー