JavaScriptの基礎文法まとめ

2020年12月28日JavaScript

JavaScriptの基礎文法を理解しましょう。

ここではJavaScriptの基礎中の基礎の部分が書かれているので、
しっかりと確認しておきましょう。

JavaScriptを書く場所について

  • HTML内で記述する
  • 別のJavaScriptフォルダから参照する

JavaScriptをHTML内で書くときは、scriptタグで囲って、その中に書きます。
scriptタグはどこでも書けるのですが、基本的にはbodyタグの終了タグの前に書きます。

別のJavaScriptフォルダから参照する場合は、次の文言をbodyタグの終了タグの直前に記述して読み込みます。

<script src="ファイルの階層/ファイル名.js></script>

'use strict’;

JavaScriptを書くときは’use strict’;を宣言します。
'use strict’;は、厳密なエラーチェックをするための宣言です。
書かなくてもJavaScriptは認識されるのですが、書いておくとエラーが発見しやすくなるので便利です。

console.log

console.logはブラウザのコンソール部分に表示するための文言です。

JavaScriptでは大文字と小文字を厳密に区別するので、注意が必要です。

JavaScriptでは、 シングルクオテーション(’)かダブルクオテーション(")で囲うことができます。
下のどちらでもOKです。

console.log('hi!');
console.log("hi!");

次の文はダメです。

console.log('hi! It's me');

文章内でシングルクオテーション(')を使うのなら、ダブルクオテーション(")で囲ってあげる必要があります。
もしくは、シングルクオテーションの直前にバックスラッシュを追加すると認識されます。

バックスラッシュ+何か

バックスラッシュ+何かでいろいろできます。
バックスラッシュ+n→改行
バックスラッシュ+t→タブ

文字列の連結

+をいれることで文字列の連結ができる。

console.log('hi!' + "It's me");

四則演算

JavaScriptでは、次の四則演算が可能です。

  • +足し算
  • -引き算
  • *掛け算
  • / 割り算
  • % 余り
  • ** べき乗

これらの記号は、演算子と呼びます。

算数と同じで、+-より*/のほうが優先して計算されます。
そのため、算数と同じで+-を優先させたいときは、()で囲ってあげましょう。

定数

がずお君がマンガを月に3冊500円で買っているとすると、いくらになるかを計算したい場合、次のように書きます。

console.log(500 * 3);

また、月5冊で計算したい場合、また次のように書く必要がでてくる。

console.log(500 * 5);

ただ、これだと500が何かわかりづらいです。
さらに値段が変わったときに変更するのが大変になります。
そこで、わかりやすい名前をつけるために、定数を使います。

定数を使うには、次のように宣言してあげる必要があります。

const price = 500;

priceの部分は、自分で自由に決めることができます。

この「=」は「代入」を意味します。
左に右のものを代入するという意味です。

また、constというのは、constant(定数)のことです。
定数には、再代入はできません。

例えば、

const price = 500;
console.log(price * 3);

price = 600;
console.log(price * 3);

とするとエラーが出ます。

値が変化するのであれば、変数を使います。

変数

変数は、letで宣言します。

let price = 500;
console.log(price * 3);

変数のほうが、定数より自由度が高い分、なにがどんな値なのかわかりづらくなりやすいので注意が必要です。
なるべく定数を使ってコロコロと値が変わるものを減らしてあげることが望ましいです。

letではなく、varという書き方もありますが、それはJavaScriptの古いバージョンで使われていた書き方なので今は非推奨です。
そのため、今からJaveScriptを勉強する場合は変数はletとおぼえておくといいでしょう。

宣言による機能の違い

タイプ 再代入 スコープ 初期化 再宣言
let ブロック
const ブロック
var 関数 undefined

varを使うとブロックスコープは無視されるため、関数スコープのみです。
またホイスティングでもvarのみundefinedが初期値になります。
また、再宣言はvarのみ可能ですが、エラーの元なので使わない方がいいでしょう。
varは非推奨なので、使わないようにしましょう。

定数と変数の命名規則について

定数と変数の名前の付け方には、いくつかルールがあるのでみていきましょう。

  • 英数字、$、_のみ使用可能
  • 数値からは始められない
  • 大文字小文字は区別される
  • 予約語は使えない

名前の付け方は、悩むけど、最初はきれいなコードはかけないものです。
それよりもどんどん書いて、他のコードを見て学んでいくことで、どんな名前がわかりやすいかがわかるようになり、名前の付け方で迷うことも減ってくるでしょう。

変数の計算

変数に変数を足したいということはよく起こります。

let price = 100;
price = price + 10;

上のように書きますが、よく書くので省略した書き方が用意されています。

price += 10;

これは他の演算子でも使えます。
たとえば、

price *= 10;

変数と1を使うケースはもっと多いため、さらに省略された書き方が用意されています。

price = price + 1;
price += 1;
price ++;

という書き方ができます。

なお、マイナスもこの書き方ができます。

price--;

JavaScriptのデータ型

JavaScriptのデータ型には、プリミティブ型とオブジェクトがあります。
オブジェクトはプリミティブ型以外を指します。
JavaScriptでは以下のデータを扱うことができます。

データ型
プリミティブ型 文字列(String) 'おはよう。’ “Good"
数値(Number) 1 2 3 -20 5.5
undefined undefined
Null null
真偽値(Boolean) true false
シンボル(Symbol) 一意の値
BigInt 15n
オブジェクト(プリミティブ型以外) オブジェクト(Object) {s:100, m: 200}

データ型の確認方法

これらのデータ型は、typeofという演算子を使うとデータ型を調べることができます。

console.log(typeof 'こんにちは');
console.log(typeof 100);
console.log(typeof true);
console.log(typeof undefined);
console.log(typeof null);

その際、nullだけobjectとでてくるのですが、javaScriptの有名なバグなので、知っておきましょう。

プリミティブ型

プリミティブ型の変数には値が格納されます。
その値は一度作成すると変更することができません。
このプリミティブ型の性質をimmutable(不変)といいます。
letで宣言すると再代入できますが、メモリ空間でのアドレスの参照場所が変更されるだけで、メモリ空間上に一度設定した値を変更しているのではないため、immutableとなります。
また、プリミティブ型でメソッドがいろいろ使える仕組みとしてラッパーオブジェクトの存在があります。
こちらの記事を参考にしてみてください。

undefined

undefinedは定義されていないという意味です。
宣言していない、値を代入していないときに現れます。

null

nullはナルとかヌルと呼ばれています。値がなにも入っていない空の意味です。

シンボル(Symbol)とは

シンボル(Symbol)とは、プロパティの重複を避けるために、必ず一意の値を返す関数のことです。
シンボルはプリミティブ型です。

const symbol = Symbol();
console.log(symbol); //Symbol()

内部で一意の値にするため、コンソールで表示されるときは、Symbol()となります。

const hi1 = Symbol('hi');
const hi2 = Symbol('hi');
console.log(hi1, hi2); //Symbol(hi) Symbol(hi)
console.log(hi1 === hi2);//false

見た目は同じで中身は異なる一意の値です。

const str = new String('yamada');
console.log(str);
//Symbol(Symbol.iterator)

ES6導入時に、iteratorという既存のコードが存在した場合に壊してしまうので、Symbol(Symbol.iterator)として必ず一意の値にすることで被らないようにする、という目的で導入されました。
そのため、シンボルは、ES5からES6のバージョンに上がる際に、既存のコードを破壊しないために導入された一意の値を得るためのプロパティ識別子と考えましょう。
JavaScirptで開発する人にはあまり使う用途がなく、JavaScriptエンジンを作っている人たちが使うデータ型となります。

データ型であるオブジェクト

オブジェクトは、名前がついた参照を管理する入れ物です。
データ型であるオブジェクトには、オブジェクトの他にも、配列や関数など、プリミティブ型以外のすべてが含まれます。

データ型であるオブジェクトは、変数の参照が格納されます。
オブジェクトの値を変更するとき、参照先を変更するのではなく参照先にある値を変更することになるので、値の変更をすることができます。
このオブジェクトの性質をmutable(可変)といいます。
オブジェクトの場合、変数が{}への参照を格納します。その{}の中の変数が値を格納しています。その値というのはメモリ空間のどこかに存在していますが、オブジェクトはそれへの参照を保持しているだけということです。プリミティブ型と違い、変数と値の間に1段階入っているので、オブジェクトは{}を参照しているだけのため、値の変更にも対応できます。

オブジェクトの基本操作については、JavaScriptのオブジェクトの基本操作方法を参考にしてみてください。

プリミティブ型とオブジェクトのコピーの違い

プリミティブ型の値のコピーは、参照先の値自体がコピーされます。
オブジェクトのコピーでは、オブジェクトの参照がコピーされます。

プリミティブ型のコピーの例

例えば、プリミティブ型の数値を使った例を紹介してみます。

{
  let num1 = 1;
  let num2 = num1;
  num1 = 3;

  console.log(num1); //3
  console.log(num2); //1
}

num1=1という情報がコンピュータ上のどこかに格納されて、
num2はそのnum1の値1がコピーされて、コンピュータ上のどこかに格納されます。

そして、下のように変更されます。
num1には3が代入されて、結果は上の通りnum1=3,num2=1となます。

データ型がオブジェクトのコピーの例

次に、同じようなことを、データ型がオブジェクトである配列でやってみます。

{
  let num1 = [1, 2];
  let num2 = num1;
  num1[0] = 3;

  console.log(num1); //[3, 2]
  console.log(num2); //[1, 2]ではなく[3, 2]
}

num1は最初1,2で、その後num1の0番目に3が代入されたので、3,2となります。
num2はnum1が1,2のときに代入されたので、1,2となるはずなのですが、
結果は、3,2になります。

なぜでしょうか?
この挙動の理由について、詳しくみていきましょう。

まず、num1が下のようなデータとして、コンピュータ上のどこかに格納されます。
次に、num2=num1とすると、num1の値がコピーされるのではなくて、
num1の座標がどこにあるのかという情報だけが与えられて、そこにnum2という名前がつけられるという構造になります。
したがって、num1の値が変わればnum2の値も同じようにかわるということです。

複雑なデータ型はデータ量が多く負荷がかかるため、このような形式をとることでメモリ効率を上げています。

データ型がオブジェクトでプリミティブ型と同じ結果を得る方法

データ型がオブジェクトをプリミティブ型の結果のように、コピーするにはどうしたらいいのでしょうか?

そのためには、num2にnum1を代入するときに、スプレッド構文にして値を格納します。

つまり、下の通りです。

{
  let num1 = [1, 2];
  let num2 = [...num1];//スプレッド構文
  num1[0] = 3;

  console.log(num1); //[3, 2]
  console.log(num2); //[1, 2]
}

スプレッド構文を使うことで、参照先のコピーではなく、値をコピーすることができます。
よって、num1とnum2の参照先は全く別になるため、num1を変更してもnum2に影響はなく、結果プリミティブ型と同じ結果を得ることができます。

プリミティブ型とオブジェクトの比較の違い

プリミティブ型は、値が比較されます。
オブジェクト参照が比較されます。

const a = {
  p: 3
}
const b = {
  p: 3
}
console.log(a === b);//false
console.log(a.p === b.p);//true

JavaScriptの計算での注意点

"で囲めば文字列として認識されるというルールなのですが、

console.log('9' * 2);
console.log('3' - '1');

とした場合、数値として計算されます。これはマイナスなどは数値の計算にしか使用されないため数値に変換して計算されます。

しかし、文字列連結の意味で「+」記号は使っているので、

console.log('4' + 2);

とすると42と出てくる点に注意しましょう。
これらはすべて暗黙的な型変換が行われているためです。
暗黙的な型変換については、JavaScriptの言語的な特徴についてを参照してみてください。

文字列を整数に変換する演算子parseIntを使うことで、ちゃんと計算することができます。

console.log(parseInt('4', 10) + 2);

数字にできないものをparseIntすると、NaNと出てきます。

console.log(parseInt('hi', 10);

NaNは、Not a Number(数値ではない)の意味です。

比較演算子

比較演算子には、次の種類があります。

  • >
  • <
  • >=
  • <=
  • ==(データ型を変換してから一致するかを確認する)
  • ===(データ型も含めて一致)
  • !==(イコールではない)

上の4つは算数と同じ意味です。

厳格な等価性(===)と抽象的な等価性(==)の違い

  • 厳格な等価性(===):型の比較あり
  • 抽象的な等価性(==):型の比較なし

という違いがあります。
たとえば次のケースをみてみましょう。

1 == '1’だとtrueになり、
1 === '1’だとfalseになります。

==の場合は型の変換をしてから左辺と右辺が一致しているのかを確認します。
右辺の1が数値であるのに対し、’1’は文字列ではありますが、データ型を一旦booleanのtrue/falseに変換します。1はtrue、0がfalseなので、1 == trueとなり、trueとなります。

1 == trueとしてもtrueになりますし、0 == falseとしてもtrueとなります。

等価性は、なるべる厳格な等価性(===):を使いましょう。

抽象的な等価性の比較については、ECMAScriptのThe Abstract Equality Comparison Algorithmに詳しく仕組みがかかれています。

falsyとtruthy

falsyな値とは、Booleanで真偽値に変換したときにfalseになる値のことです。
truthyな値とは、falsyな値以外のことです。

falsyな値
truthyな値
false,
null,
0,
undefined,
0n,
NaN,
“"
falsyな値以外の値

0nはBigIntです。
NaNはNot a Numberの略で、数値と期待されている場合で数値でなかったときにNaNが返されます。preseInt(“")など空を整数化しようとするとNaNが返されます。

true,falseの確認の仕方は、Booleanを使うといいです。

console.log(Boolean(0));

これはfalseが返されます。

console.log(Boolean('こんにちは'));

これはtrueが返されます。

一見すると、こんにちはでtrueとか、1だったらtrueで0だったらfalseというのは意味がわからないけれども、そういう仕様と考えましょう。

プログラミングの学習をすすめると条件分岐の辺りで当たり前のようにでてくるので、おざなりにせず覚えておくのがおすすめです。

テンプレートリテラル

テンプレートリテラルを使うと、バッククオート(`)で囲むことコンテンツの指定方法で、変数や定数を文字列に組み込むことができます。
変数や定数は、${}の中にいれます。

たとえば、次のような文をつくることができます。

const score = 80;
let test = '算数';
const name = 'がずお';

cosole.log(`${name}君の${test}の点数は${score}点です。`);
//がずお君の算数のテストは80点です。

この文をテンプレートリテラルを使わないと、次のような書き方になります。

const score = 80;
  let test = '算数';
  const name = 'がずお';
  
  cosole.log(name + '君の' + test + 'の点数は' + score + '点です。');
  //がずお君の算数のテストは80点です。