🕶️

Reactのための"モダンJavaScript"基本まとめ

2024/03/03に公開

”モダンJavaScript”とは?

Reactの勉強を本格的に始めようとReact入門系の本を2冊買ってみたところ、どちらも「React学習の前に”モダンJavaScript”の機能について知っている必要がある」というお話が載っていました。具体的にはES2015から追加されたアロー関数やスプレッド構文などについて知っていないと、React学習に支障をきたすとのことだったので、復習も兼ねて本で紹介されていたモダンJavaScriptの機能について自分なりにまとめてみたいと思います。本記事では構文などの文法的な話を中心に扱います。

const, let

まずは変数宣言について。結論から言うと基本的にはconstを使って変数の宣言をし、constが使えない場合はletを使う方針のようです。以下、それぞれについての特徴をまとめます。

const

constは再宣言と上書きを禁止する変数の宣言です。定数を意味するconstantから来ているようです。具体的には以下の例はエラーになります。

const message = "Hello";

const message = "World"; // messageを再宣言しようとしているためエラー
message = "World"; // messageを上書きしようとしているためエラー

ただし、constを「変更できない変数」と考えてしまうのは誤りです。
真偽値、数値、文字列といったプリミティブ型のデータは変更できませんが、オブジェクトや配列、関数といったオブジェクト型のデータは、constで定義しても変更が可能です。

// 配列を変更する例
const array = [0, 1, 2];
array[0] = 3;

console.log(array); // [3, 1, 2]

// オブジェクトを変更する例
const obj = {
  name: "somahc",
  favorite: "sushi",
};
obj.favorite = "ramen";

console.log(obj); // {name: "somahc", favorite: "ramen"}

let

letは再宣言はできないものの、上書きができる変数の宣言に使います。

let message = "Hello";

let message = "World!"; // messageを再宣言しようとしているためエラー
message = "World!"; // messageを上書きしているためOK

上述した通り、基本constを使い、どうしても無理な場合にletを使うのがセオリーのようです。なお、再宣言も上書きも可能な従来形式のvarによる変数宣言も可能ですが、危険であるため使うことはないようです。

テンプレート文字列

テンプレート文字列は、文字列の中で変数を展開することを可能にする機能です。``(バッククォート)と${}を使うことで実現できます。
以下のように使うことができます。

const name = "somahc";
const favorite = "sushi";

const message = `私は${name}です。好きな食べ物は${favorite}です。`;

console.log(message); // 私はsomahcです。好きな食べ物はsushiです。

また、${}内ではJavaScriptが実行でき、${2 + 3}のように関数や計算式を書くこともできるようです。

アロー関数

アロー関数は関数の新たな表記法で、=>という一風変わった矢印のような記号を使うのが特徴です。アロー関数を用いることで関数定義をより簡潔に行うことができます。

// 従来の関数定義
function func(value) {
    return value;
};

console.log(func("Hello world!")); // Hello world!

// アロー関数
const arrowFunc = (value) => {
    return value;
};

console.log(arrowFunc("Hello world!")); // Hello world!

funcarrowFuncも引数で与えられた値を返すだけの関数ですが、アロー関数は書き方がかなり違っているのがわかります。functionと言う言葉は使わずに()に引数を書き、{}に処理内容を書いていきます。
ただし、アロー関数には条件によって以下2つの省略記法が使えることがあります。

省略ルール1「引数が1つの場合、()を省略できる」

先ほど例で挙げた関数のように引数が1つの場合()を省略することが可能です。

// 省略なし
const arrowFunc = (value) => {
    return value;
};

// 省略あり
const arrowFunc2 = value => {
    return value
};

引数が2つ以上の場合は、()を省略できないことに注意。

省略ルール2「処理が単一行の場合、{}returnを省略できる」

また、処理が単一行の場合は{}returnを省略することが可能です。

// 省略なし
const arrowFunc = (value) => {
    return value;
};

// {}とreturn省略
const arrowFunc3 = (value) => value;

// ()も省略するとこうなる
const arrowFunc4 = value => value;

慣れていないと関数定義であることすら気が付かないほど簡潔になっています。
なお、()を用いて複数行になる戻り値をまとめることもできるようです。

const arrowFunc5 = (value1, value2) => (
    {
        name: value1,
        favorite: value2,
    }
);

console.log(arrowFunc5("somahc", "sushi")) // {name: "somahc", favorite: "sushi"}

分割代入

分割代入を用いることでオブジェクトや配列から値を効率よく抜き出すことができます。

// 従来の方法。いちいちuserInfo.~を書かなければならず、面倒。
const userInfo = {
    name: "somahc",
    favorite: "sushi",
};

const message = `私は${userInfo.name}${userInfo.favorite}が好きです。`;
console.log(message); // 私はsomahc。sushiが好きです。

// 分割代入
const userInfo = {
    name: "somahc",
    favorite: "sushi",
};

const {name, favorite} = userInfo;

const message = `私は${name}${favorite}が好きです。`;
console.log(message); // 私はsomahc。sushiが好きです。

上のように変数の宣言部で{}を使うことで変数名と一致するプロパティをオブジェクトから抽出してくれます。また、nameだけのように、オブジェクトのプロパティの一部のみを抽出して使うことも可能です。プロパティ名と一致さえしていればconst {favorite, name} = userInfo;のように順番を逆にしても問題ないです。

さらに、:を使うことで以下のようにプロパティに別名をつけて扱うこともできます。

const userInfo = {
    name: "somahc",
    favorite: "sushi",
};

const {name: username} = userInfo;

const message = `ユーザーネームは${username}です。`;
console.log(message); // ユーザーネームはsomahcです。

配列の分割代入の注意点

配列の分割代入もオブジェクトの分割代入とほぼ同じですが、オブジェクトと違い配列に格納されている順番に要素が取り出される点が違います。また、変数名も自分で設定します。

const userInfo = ["somahc", "sushi"];

const [name, favorite] = userInfo; // const [favorite, name]とすると逆になってしまう

const message = `私は${name}${favorite}が好きです。`;
console.log(message); // 私はsomahc。sushiが好きです。

デフォルト値

関数の引数・オブジェクトの分割代入の際、=を使うことで値が指定されなかった場合に使われるデフォルト値を指定することができます。

// 関数
const introduction = (name = "匿名希望") => console.log(`私は${name}です。`);

introduction("somahc") // 私はsomahcです。
introduction() // 私は匿名希望です。(デフォルト値を指定していないとundefinedになってしまう)

// 分割代入
const userInfo = {
    favorite: "sushi",
};

const {name = "匿名希望"} = userInfo;

const message = `私は${name}です。`;
console.log(message); // 私は匿名希望です。

スプレッド構文

配列・オブジェクトの展開

スプレッド構文(...)を使うことで配列やオブジェクトを展開することができます。

// 展開の例。要素を順番に展開してくれる。
array1 = [0, 1, 2, 3, 4, 5];

console.log(array1); // [0, 1, 2, 3, 4, 5]
console.log(...array1); // 1 2 3 4 5

// 関数と組み合わせた例。スプレッド構文で引数の表記がシンプルに。
array2 = [3, 5];

const tashizan = (value1, value2) => value1 + value2;

console.log(tashizan(array2[0], array[1])) // 8
console.log(tashizan(...array)) // 8

スプレッド構文で要素をまとめる

スプレッド構文を利用して、以下のように要素をまとめることも可能です。

array = ["Germamy", "Spain", "Japan", "Korea", "China"];

const [europe1, europe2, ...asia] = array;
console.log(europe1); // Germany
console.log(europe2); // Spain
console.log(asia); // ["Japan", "Korea", "China"]

コピー・結合

要素のコピーや結合にもスプレッド構文は用いられます。例は配列のみですが、オブジェクトも同様にコピーや結合が可能です。

array1 = ["Germany", "Spain"];
array2 = ["Italy", "UK"];

// 要素のコピー
const copiedArray1 = [...array1];

console.log(copiedArray1); // ["Germany", "Spain"]

// 要素の結合
const europeCountries = [...array1, ...array2];

console.log(europeCountries); // ["Germany", "Spain", "Italy", "UK"]
「=」によるコピーについて

copiedArray1 = array1のように=を使ったコピーもできますが、要素の情報がメモリ内のどこに保存されているかを示す参照値まで引き継がれてしまい、変更がコピー元にまで及んでしまうため、通常はスプレッド構文によるコピーを行うそうです。

オブジェクト省略記法

オブジェクトのプロパティ名と利用する変数名が同じ場合、:以降を省略できます。

// 省略なし
const name = "somahc";
const favorite = "sushi";

const userInfo = {
    name: name,
    favorite: favorite,
};

console.log(userInfo); // {name: "somahc", favorite: "sushi"}

// 省略あり
const name = "somahc";
const favorite = "sushi";

const userInfo = {
    name,
    favorite,
};

console.log(userInfo); // {name: "somahc", favorite: "sushi"}

オブジェクト定義の冗長な繰り返しを省略し、簡潔に書くことができています。

まとめ

アロー関数など、自分で調べて使ったことがあったものも含まれていましたが、本を使って改めてモダンJavaScriptについて学ぶことで知らなかった文法などについて整理することができました。Reactを学んでいく際にJavaScriptが理解できず挫折してしまった、、ということがないように一度しっかり勉強すると役に立ちそうです。

参考文献

「モダンJavaScriptの基本から始める React実践の教科書」
https://amzn.asia/d/iNrOfqo

GitHubで編集を提案

Discussion