📖

JavaScript ES5以前とES6(ES2015)以降の違いについて

2022/05/10に公開

文字列を囲む引用符について

JavaScript では、文字列を囲む引用符として、
シングルクォーテーションとダブルクォーテーションを使用することができます。

コメントアウトについて

1つの行内でコメントアウトする場合、//を使います。
また、 複数の行にまたがってコメントアウトする場合、//を使います。

※下記コード内の「 // => ○○○」はconsole.logで出力される内容とします。

varの変数宣言、変数上書き、変数再宣言について(ES5)以前

varの変数宣言

var val1 = "変数宣言";
console.log(val1); // => 変数宣言

var変数は上書き可能

val1 = "変数を上書き";
console.log(val1); // => 変数を上書き

var変数は再宣言可能

var val1 = "変数を再宣言";
console.log(val1); // => 変数を再宣言

let、constの変数宣言、変数上書き、変数再宣言(ES6以降)

letの変数宣言

let val2 = "変数宣言";
console.log(val2); // => 変数宣言

let変数は上書き可能

val2 = "変数を上書き";
console.log(val2); // => 変数を上書き

let変数は再宣言不可能

let val2 = "変数を再宣言";  // => エラーになる

constの変数宣言

const val3 = "変数val3を宣言";
console.log(val3); // => 変数val3を宣言

const変数は上書き不可能

val3 = "変数val3を上書き"; // => エラーになる

const変数は再宣言不可能

const val3 = "変数を再宣言"; // => エラーになる

表にまとめると下記のような感じです。

変数宣言 変数上書き 変数再宣言
var
let ×
const × ×

こうして見るとconstは変数宣言できるだけに見えます。
しかし、constでも変更できるものがあります。

constで宣言したオブジェクトのプロパティは変更、追加が可能

constでオブジェクトを宣言、プロパティにnameとageを持たせて
nameの値を太郎、ageの値を18とする。

const val4 = {
		name: "太郎",
		age: 18,
};
console.log(val4);  // => Object{name: "太郎",  age: 18}

nameの値を変更してみる。

const val4 = {
		name: "太郎",
		age: 18,
};
val4.name = "次郎" 
console.log(val4); // => Object{name: "次郎",  age: 18}

さらに、プロパティにareaを追加しみる。

const val4 = {
		name: "太郎",
		age: 18,
};
val4.name = "次郎" 
val4.area = "東京"
console.log(val4); // => Object{name: "次郎",  age: 18,  area: "東京"}

このようにconstであってもオブジェクトであれば、変更、追加が可能。

constで宣言した配列は変更、追加が可能

constで配列を宣言

const val5 = ["dog" , "cat" ];
console.log(val5); // => ["dog", "cat"]

配列の0番目をpigに変更、また、push関数を使って配列にdolphineを追加

const val5 = ["dog" , "cat" ];
val5[0] = "pig";
val5.push("dolphine") 
console.log(val5); // => ["pig", "cat", "dolphine"]

このようにconstであっても配列であれば、変更、追加が可能。
※ちなみにReactでは、ほとんどの変数はconstで宣言する。

文字列と変数の結合(ES5)以前

文字列と変数の結合

const name = "三郎";
const age = 15;
const message = "私の名前は" + name + "です。年齢は" + age + "です。";
console.log(message); // => 私の名前は三郎です。年齢は15です。

文字列と変数を結合するたびに「+」や「"」を入力しないといけなかった。

テンプレート文字列を使った、文字列と変数の結合(ES6以降)

テンプレート文字列を使った、文字列と変数の結合

const name = "三郎";
const age = 15;
const message = `私の名前は${name}です。年齢は${age}です。`;
console.log(message); // => 私の名前は三郎です。年齢は15です。

テンプレート文字列の場合、全体をバッククォート「`」で囲い、変数は${}で囲う。
このようにテンプレート文字列は簡潔に記述できます。
また、テンプレート文字列には、改行を含めることもできます。

従来の関数(ES5)以前

const funk1 = function (str) {
		return str;
}
console.log(funk1("funk1関数です。"));  // => funk1関数です。

関数リテラルで分かりにくい。

アロー関数(ES6以降)

const funk2 = (str) => {
		return str;
}
console.log(funk2("funk2関数です。"));  // => funk2関数です。

(引数) => {関数の本体}となり分かりやすい。

アロー関数(ES6以降)は、関数の本体が一文のとき                                      「{}」や「return」を省略できる。

省略なしの場合

const funk3 = (num1, num2) => {
		return num1 + num2;
}
console.log(funk3(10, 30));  // => 40

省略した場合

const funk3 = (num1, num2) => num1 + num2;
console.log(funk3(10, 30)); // => 40

コンソールログに出力される値は同じだが、省略した方が見やすく感じる。
※関数についての詳細(関数リテラルやthisの挙動の違い等)は割愛する。

オブジェクトに代入する場合(ES5)以前

const myprofile = {
		name: "太郎",
		age: 18,
};
const message = `私の名前は${myprofile.name}です。年齢は${myprofile.age}です。`;
console.log(message);  // => 私の名前は太郎です。年齢は18です。

オブジェクトのプロパティが増えていく度に、テンプレート文字列にmyprofile.を入力するのが面倒

オブジェクトに分割代入する場合(ES6以降)

const myprofile = {
		name: "太郎",
		age: 18,
};
const { name , age} = myprofile 
const message = `私の名前は$(name}です。年齢は${age}です。`;
console.log(message);  // => 私の名前は太郎です。年齢は18です。

const { name , age} = myprofileの1文が分割代入。
分割代入することで、テンプレート文字列myprofile.を入力する必要がなくなる。

デフォルト引数

引数に「太郎」を設定した場合

const hello = (name) => console.log("こんにちは!${name}さん!");
hello("太郎");
// => こんにちは!太郎さん!

引数に値を設定しなかった場合

const hello = (name) => console.log("こんにちは!${name}さん!");
hello();
// => こんにちは!undefinedさん!

引数が空の状態なので、undefinedになる。

引数に初期値として「"近藤"」を設定した場合

const hello = (name = "近藤") => console.log("こんにちは!${name}さん!");
hello();
// => こんにちは!近藤さん!

※引数が空の状態だが、初期値に近藤とあるので、undefinedにはならない。

配列の展開

const arr1 = [1, 2]
const sumFunk = (num1, num2) => console.log(num1 + num2);
sumFunk = (arr1[0], arr1[1])
// => 3

従来の配列の展開であれば(arr1[0], arr1[1])と入力する必要があった。

スプレッド構文を使った配列の展開

const arr1 = [1, 2]
const sumFunk = (num1, num2) => console.log(num1 + num2);
sumFunk = (...arr1)
// => 3

※カンマ3つ(...)を入れることで、引数にすべての配列を展開することができる。

配列のコピー

const arr3 = [11, 22];
const arr4 = [33, 44];
const arr5 = [...arr3];
arr3[0] = 55;
console.log(arr5);  // => [11, 22]
console.log(arr3);  // => [55, 22]

※arr3の内容をarr5にコピーしている形になるが、arr3の配列内の値を変えてもarr5の配列内の値は変わらない。参照を引き継がない。

const arr4 = [33, 44];
const arr6 = arr4;
arr6[0] = 99;
console.log(arr6)  // => [99, 44]
console.log(arr4)  // => [99, 44]

※arr4の内容をarr6にコピーしている形になる、arr6の配列内の1番目の値を変えると、arr4の配列内の1番目の値も変わる。参照を引き継ぐ。

配列の結合

const arr3 = [11, 22];
const arr4 = [33, 44];
const arr7 = [...arr3, ...arr4];
console.log(arr7); // => [11, 22, 33, 44]

※前から順番にarr3を展開、そのあとarr4を展開する。

配列のループ処理(ES5)以前

const nameArr = ["太郎", "次郎", "三郎"];
for (let index = 0; index < nameArr.length; index++) {
		console.log(nameArr[index]); 
}
// => 太郎 次郎 三郎

コンソールログで出力すると配列の中身が1つずつ展開されている。

map関数を使った配列のループ処理(ES6以降)

const nameArr = ["太郎", "次郎", "三郎"];
const nameArr2 = nameArr.map((name) => {
		return name;
})
console.log(nameArr2);  
// => ["太郎", "次郎", "三郎"]

※nameArr配列から引数nameの値を1つずつ取って、nameArr2配列に順番に格納する。
これは、配列に格納されている状態がコンソールログに出力されている状態。

配列の中身が1つずつ展開する場合

const nameArr = ["太郎", "次郎", "三郎"];
nameArr.map((name) => console.log(name));

配列のループ処理(ES5)以前の内容と比べると短くなっている。

map関数の第2引数にindexを取り、テンプレート文字列と組み合わせてみる

const nameArr = ["太郎", "次郎", "三郎"];
nameArr.map((name, index) => console.log(`${index + 1}番目は${name}です`));
// => 1番目は太郎です 2番目は次郎です 3番目は三郎です

※map関数はある条件に一致するものを加工して、新しい配列を生成する。

filter関数を使った配列のループ処理

const numArr = [1, 2, 3, 4, 5];
const newNumArr = numArr.filter((num) => {
		return num % 2 === 1;
});
console.log(newNumArr);  // => [1, 3, 5]

※filter関数はある条件に一致するものを取り出して、新しい配列を生成する。

map関数を使った配列のループ処理でも条件式は適用できる

const nameArr = ["太郎", "次郎", "三郎"];
const newNameArr = nameArr.map((name) => {
		if (name === "三郎") {
				return name
		} else {
				return `${name}さん`
		}
})
console.log(newNameArr);  // => ["太郎さん", "次郎さん", "三郎"]

名前にさん付けする、しないという条件を付けている。

三項演算子

条件がtrueの時「? "trueです"」 が実行される、条件がfalseの時「: "falseです"」が実行される。

const val1 = 1 > 0 ? "trueです" : "falseです";
console.log(val1);  // => trueです

1は0より大きいので?の内容が返る。
※分かりにくいが、「? "trueです"」 と 「:"falseです"」に別れて設定されている。

const val1 = 1 > 5 ? "trueです" :"falseです";
console.log(val1); // => falseです

1は5より大きくないのでfalseの内容が返る。

const checkSum = (num1, num2) => {
		return num1 + num2 > 100 ? "100を超えています" : "100を超えていません";
}
console.log(checkSum(40, 50));  // => 100を超えていません

40+50をしても100より小さいので「100を超えていません」が出力される。

論理演算子の使い方(&& || )

||は左側がfalseなら右側を返す。

const num = 1000
const num1 = num || "右側を返してます"
console.log(num1); // => 1000

||は左側がtrueなら左側を返す。

const num = null
const num1 = num || "右側を返してます"
console.log(num1); // => 右側を返してます

&&は左側がtrueなら右側を返す。

const num2 = 1000
const num3 = num2 && "右側を返してます"
console.log(num3); // => 右側を返してます

&&は左側がfalseなら左側を返す。

const num2 = null
const num3 = num2 && "右側を返してます"
console.log(num3); // => null

カッコ内(flag1 || flag2)がtrue判定の場合のみ、if文の中が実行される。

const flag1 = true;
const flag2 = false;
if (flag1 || flag2) {
		console.log("true判定");
}
// => true判定
const flag1 = true;
const flag2 = false;
if (flag1 && flag2) {
		console.log("true判定");
}
// => (trueではないので何も出力されない)

Discussion