はじめに
他の人が書いたJavaScriptのコードを読む機会があり「この構文ってどういう意味?」「この構文の呼び名は?」となることがあったので、調べたついでに気になった構文をまとめました。
自分用のメモとして簡易に記述しているので、厳密な定義を知りたい方は最後の参考サイトをご覧ください。
真と偽:truthy, falsy
構文まとめの前に、構文の中に式がたくさん出てくるので、真になる値と偽になる値を軽く整理しておきます。
真になる値:truthy
// true
console.log(Boolean(true)); // true
// ゼロでない数値
console.log(Boolean(10)); // true
console.log(Boolean(-20)); // true
// 空でない文字列
console.log(Boolean("Hello")); // true
// オブジェクトなどの参照
console.log(Boolean({})); // true
console.log(Boolean([])); // true
console.log(Boolean(new Date())); // true
console.log(Boolean(function(){})); // true
偽になる値:falsy
// false
console.log(Boolean(false)); // false
// ゼロ
console.log(Boolean(0)); // false
// 空文字
console.log(Boolean("")); // false
// nullなど
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
代入系
Null 合体代入 (??=)
構文
変数 ??= 式
説明
変数がnullまたはundefinedでない場合、変数の値は変わりません。
変数がnullまたはundefinedの場合、式の値が変数に代入されます。
サンプル
let a = 0;
a = 123;
a ??= 456;
console.log(a);
// 123
a = null;
a ??= 456;
console.log(a);
// 456
論理積代入 (&&=)
構文
変数 &&= 式
説明
変数の評価が真の場合、式の値が変数に代入されます。
サンプル
let a = 0;
a = true;
a &&= 123;
console.log(a);
// 123
a = false;
a &&= 123;
console.log(a);
// false
a = null;
a &&= 123;
console.log(a);
// null
a = 10;
a &&= 123;
console.log(a);
// 123
論理和代入 (||=)
構文
変数 ||= 式
説明
変数の評価が偽の場合、式の値が変数に代入されます。
サンプル
let a = 0;
a = true;
a ||= 123;
console.log(a);
// true
a = false;
a ||= 123;
console.log(a);
// 123
a = null;
a ||= 123;
console.log(a);
// 123
a = 10;
a ||= 123;
console.log(a);
// 10
配列:分割代入
構文(一部抜粋)
const [変数1, 変数2] = 配列;
const [変数1, , 変数2] = 配列;
説明
配列から要素を取り出して、変数1、変数2に代入します。
間を飛ばすこともできます。
サンプル
let array = [100, 200, 300];
const [a1, a2] = array;
console.log(a1, a2);
// 100 200
const [b1, ,b3] = array;
console.log(b1, b3);
// 100 300
オブジェクト:分割代入
構文(一部抜粋)
const {変数1, 変数2} = オブジェクト;
const { a: 変数1, b: 変数2 } = オブジェクト;
説明
オブジェクトからプロパティを取り出して、変数1、変数2に代入します。
サンプル
let obj = {id: 100, name: 'test', value: 'abc'};
const {id, name} = obj;
console.log(id, name);
// 100 "test"
const {id: i, name: n} = obj;
console.log(i, n);
// 100 "test"
残余プロパティ
構文
const {変数1, ...オブジェクト2} = オブジェクト1;
説明
変数1と名前が一致するオブジェクト1のプロパティをオブジェクト1から変数1へ代入します。
変数1と名前が一致しなかったオブジェクト1の残りのプロパティをオブジェクト2へ代入する。
サンプル
let obj = {id: 100, name: 'test', value: 'abc'};
const {id, ...other} = obj;
console.log(id);
// 100
console.log(other);
// {
// "name": "test",
// "value": "abc"
// }
演算子系
Null合体演算子
構文
式1 ?? 式2;
説明
式1がnullまたはundefinedでない場合、式1の値を返します。
式1がnullまたはundefinedの場合、式2の値を返します。
サンプル
x = null ?? 123;
console.log(x);
// 123
x = 999 ?? 123;
console.log(x);
// 999
カンマ演算子
構文
(式1, 式2, 式n)
説明
式がカンマで列挙されているとき、最も右側の式の値を返します。
サンプル
x = (1, null, "abc");
console.log(x);
// "abc"
三項演算子
構文
条件式 ? 真の時の式 : 偽の時の式
説明
条件式が真の場合、真の時の式を返します。
条件式が偽の場合、偽の時の式を返します。
サンプル
let greeting;
greeting = "hello"
const x = greeting == "hello" ? "こんにちは" : "その他" ;
console.log(x);
// "こんにちは"
greeting = "goodbye"
const y = greeting == "hello" ? "こんにちは" : "その他" ;
console.log(y);
// "その他"
引数系
デフォルト引数
構文
function 関数名(引数1 = デフォルトの値1, ..., 引数N = デフォルトの値N)
説明
引数に値が指定されなかった場合、デフォルトの値が引数に設定されます。
サンプル
function fnName(p1 = 10, p2 = "abc") {
console.log(p1, p2);
}
fnName();
// 10 "abc"
fnName(20, "xyz");
// 20 "xyz"
fnName(100);
// 100 "abc"
fnName(p2 = "zzz"); // 引数を指定できるわけではない
// "zzz" "abc"
fnName(undefined, "zzz");
// 10 "zzz"
fnName(null, "zzz");
// null "zzz"
スプレッド構文
構文1
関数(...配列)
説明
配列の参照を渡すのではなく、配列の要素をすべて並べて引数に渡します。
サンプル
// 関数(...配列)
const array = [1, 2, 3, 4, 5];
function fnName(a, b, c, d, e) {
console.log(a, b, c, d, e);
}
fnName(...array);
// 1 2 3 4 5
fnName(array);
// [1,2,3,4,5] undefined undefined undefined undefined
// 一つ目の引数に配列が丸ごと入っている
構文2
配列1[...配列2]
サンプル
// 配列1[...配列2]
const array1 = [1, 2, 3, 4, 5];
console.log("スプレッド構文を使った例")
const array2 = [...array1];
console.log(array2); // [1, 2, 3, 4, 5]
array2.pop(); //最後の要素を削除
console.log(array2); // [1, 2, 3, 4]
console.log(array1); // [1, 2, 3, 4, 5] 元の配列は変化なし
console.log("スプレッド構文を使わない例")
const array3 = array1;
console.log(array3); // [1, 2, 3, 4, 5] 結果は同じだが
array3.pop(); //最後の要素を削除
console.log(array3); // [1, 2, 3, 4]
console.log(array1); // [1, 2, 3, 4] 元の配列も減ってる
構文3
new オブジェクト(...配列)
サンプル
class Obj {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
array = [123, 456];
obj = new Obj(...array);
console.log(obj);
// {
// "height": 123,
// "width": 456
// }
残余引数
構文
function 関数名(変数1, 変数2, ...変数A) {
説明
可変長引数
関数が不定数の引数を配列として受け入れることができ
サンプル
function fnName(p1, p2, p3, p4, p5) {
console.log(p1, p2, p3, p4, p5);
}
array = [3, 4, 5];
fnName(1, 2, ...array);
// 1 2 3 4 5
プロパティ系
オプショナルチェイニング
オプショナルチェーン
構文(一部抜粋)
オブジェクト.変数?.変数
オブジェクト.変数?.[式]
オブジェクト.配列?.[インデックス]
オブジェクト.関数?.(引数)
obj.val?.prop;
obj.val?.[expr];
obj.arr?.[index];
obj.func?.(args);
説明
オブジェクトの途中で、undefineやnullがあっても例外が発生しない
サンプル
const rect = {height: 10, width: 20};
const obj = {id: 123, name: "test", size: null}; // まだsizeにrectを設定していない
console.log(obj.name);
// console.log(obj.size.height); // Cannot read properties of null エラーになる
console.log(obj.size?.height);
// undefined
プロパティアクセサー
ドット表記法とブラケット表記法
const rect = {height: 10, width: 20};
console.log(rect.height); // ドット表記 10
console.log(rect['height']); // ブラケット表記 10
その他
テンプレートリテラル (テンプレート文字列)
構文
`文字列 ${式}`
説明
バッククォートで囲む。
${式}を書くと、中の式が文字列に展開される。
サンプル
console.log(`計算結果、${1+1}`);
// "計算結果、2"
タグ付きテンプレート
構文
タグ名`文字列 $(式)`
説明
関数を用意しておく。
タグ名として用意しておいたタグを指定する。
続けてテンプレートリテラルを書く。
サンプル
function highlight(strings, ...values) {
result = '';
strings.forEach((string, i) => {
console.log(string, i, values[i]);
result += string
result += values[i] ? `<strong>${values[i]}</strong>` : '';
console.log(result);
});
return result;
}
const message = highlight`私の名前は${"テスト太郎"}です。年齢は${6}歳です。`;
console.log(message);
コンソール出力
"私の名前は" 0 "テスト太郎"
"私の名前は<strong>テスト太郎</strong>"
"です。年齢は" 1 6
"私の名前は<strong>テスト太郎</strong>です。年齢は<strong>6</strong>"
"歳です。" 2 undefined
"私の名前は<strong>テスト太郎</strong>です。年齢は<strong>6</strong>歳です。"
"私の名前は<strong>テスト太郎</strong>です。年齢は<strong>6</strong>歳です。"
参考
書籍
「これからはじめるReact実践入門 コンポーネントの基本からNext.jsによるアプリ開発まで」
山田 祥寛 (著)
Webサイト
MDN Web Docs
最後に
MDNのサンプルコードを読むだけでは理解しづらかったですが、サンプルコードを書いてみることで理解が深まりました。
書籍やWebサイトを読むだけでなく、自分でサンプルコードを書いてみることをオススメします。