JavaScript Primer - 迷わないための入門書#jsprimer

ECMAScript 2015以降をベースにして一からJavaScriptを学べるサイト。書籍も販売されている。

|100

自分の中で曖昧な部分と知らなかったことを中心にメモする。

第一部: 基本文法

変数と宣言

[ES2015] const

再代入できない変数の宣言とその変数が参照する値を定義する。

const 変数名 = 初期値
 
const a = "aaa",
	  b = "bbb"

[ES2015] let

再代入可能な変数を宣言する。

let a;
// aはundefinedになる
 
let a = "aaa";

var

varは同じ名前の変数を再定義できてしまう(エラーにならない)ため、意図せず同じ変数名を定義してしまう問題がある。

後方互換性のため残されているが、新しく作成するプログラムで使用するメリットはない。

データ型とリテラル

データ型

  • プリミティブ型(基本型)
    • 真偽値(Boolean)
    • 数値(Number)
    • 巨大な整数(BigInt) :ES2010から追加
    • 文字列(String)
    • undefined: 値が未定義であることを意味するデータ型
    • null: 値が存在しないことを意味するデータ型
    • シンボル(Symbol): ES2015から追加
  • オブジェクト(複合型)
    • プリミティブ型以外のデータ
    • オブジェクト、配列、関数、クラス、正規表現、Dateなど

プリミティブ型の値はtypeofでデータ型を確認できる。オブジェクトに分類される値はobjectに分類されるが、以下の例外がある。

  • 関数: "function"になる(関数は特別扱いされている)
  • null: "object"になる(仕様のバグ)

[ES2015]テンプレートリテラル

`(バッククォート)で囲んだ範囲を文字列にするリテラル。

const s = `複数行の
文字列を
入れたい`;
console.log(s);  // => '複数行の\n文字列を\n入れたい'

テンプレートリテラル内で変数の値を埋め込むことができる。

const s = "文字列";
console.log(`これは${s}です`);  // => 'これは文字列です'

オブジェクトリテラル

オブジェクトリテラルのプロパティを参照するのは、.(ドット)でつないで参照する方法と、[](ブラケット)で参照する方法がある。

const obj = {
    "key": "value"
};
// ドット記法
console.log(obj.key); // => "value"
// ブラケット記法
console.log(obj["key"]); // => "value"

演算子

等価演算子と厳密等価演算子

等価演算子(==)はオペランド同士の型が異なる場合暗黙的な型変換され、結果を予測できない挙動になる可能性があり、基本的には使用しない方が良い。

// 文字列を数値に変換してから比較
console.log(1 == "1"); // => true

例外的に等価演算子(==)が使われるのはnullundefinedの比較。厳密等価演算子(===)では二度比較する必要があるが、等価演算子(==)は一度でよい。

const value = undefined; /* または null */
// === では2つの値と比較しないといけない
if (value === null || value === undefined) {
    console.log("valueがnullまたはundefinedである場合の処理");
}
// == では null と比較するだけでよい
if (value == null) {
    console.log("valueがnullまたはundefinedである場合の処理");
}

[ES2015] 分割代入

const array = [1, 2];
// aには`array`の0番目の値、bには1番目の値が代入される
const [a, b] = array;
console.log(a); // => 1
console.log(b); // => 2

[ES2020] Nullish coalescing演算子(??)

Nullish coalescing演算子(??)は、左辺の値がnullishであるならば、右辺の評価結果を返す。

const inputValue = 任意の値または未定義;
// `inputValue`がnullishの場合は、`value`には42が入る
// `inputValue`が`0`の場合は、`value`に`0`が入る
const value = inputValue ?? 42;
console.log(value);

関数と宣言

- `return`の戻り値を省略した場合、または`return`がない関数は`undefined`が返却される
- 関数の仮引数よりも呼び出し時の引数が少ない場合、余った仮引数には`undefined`が代入される

可変長引数

function fn(...args) {
    // argsは、渡された引数が入った配列
    console.log(args); // => ["a", "b", "c"]
}
fn("a", "b", "c");

[ES2015] Rest parameters

function fn(arg1, ...restArgs) {
    console.log(arg1); // => "a"
    console.log(restArgs); // => ["b", "c"]
}
fn("a", "b", "c");

[ES2015] 関数の引数と分割代入

const user = {
    id: 42
};
// オブジェクトの分割代入
const { id } = user;
console.log(id); // => 42
// 関数の引数の分割代入
function printUserId({ id }) {
    console.log(id); // => 42
}
printUserId(user);

[ES2015] Arrow Function

// Arrow Functionを使った関数定義
const 変数名 = () => {
    // 関数を呼び出したときの処理
    // ...
    return 関数の返す値;
};
  • 関数の仮引数が1つのときは()を省略できる
  • 関数の処理が1つの式である場合に、ブロックとreturn文を省略できる
    • その式の評価結果をreturnの返り値とする
const array = [1, 2, 3];
const doubleArray = array.map(value => value * 2);
console.log(doubleArray); // => [2, 4, 6]

array.mapのパラメタは関数を渡しており、仮引数がvalueのみなので()を省略し、関数の処理が1つの式のためブロックとreturnを省略している。省略しない書きかたは以下。

const doubleArray = array.map(function(value) {
    return value * 2; 
});

同じ名前の関数宣言は上書きされる

constを使って定義するとエラーになるため、意図しない上書きを避けることができる。

const fn = (x, y) => {
    return `最後の関数 x: ${x}, y: ${y}`;
};

コールバック関数

引数として渡される関数。

const array = [1, 2, 3];
const output = (value) => {
    console.log(value);
};
array.forEach(output);

[ES2015] メソッドの短縮記法

短縮記法でない書きかた

const obj = {
    method1: function() {
        // `function`キーワードでのメソッド
    },
    method2: () => {
        // Arrow Functionでのメソッド
    }
};

短縮記法の書きかた

const obj = {
    method() {
        return "this is method";
    }
};
console.log(obj.method()); // => "this is method"