constは、オブジェクトへの不変の参照を作成しますが、これは値を変更できないという意味ではありません-いいえ、この値は変更できます。 次のコードはエラーではありません。
const foo = {}; foo.bar = 42; console.log(foo.bar); // → 42 const arr = [0, 20, 30]; arr[0] = 10; console.log(arr); // → [10, 20, 30]
ここで不変なのは、オブジェクトへの参照だけです。 constは、値({})を変数fooに割り当て、新しい割り当てがないことを確認します。 代入演算子、および単項演算子または後置演算子を使用すると、++がTypeErrorエラーをスローします。
const foo = 27; // // : foo = 42; foo *= 42; foo /= 42; foo %= 42; foo += 42; foo -= 42; foo <<= 0b101010; foo >>= 0b101010; foo >>>= 0b101010; foo &= 0b101010; foo ^= 0b101010; foo |= 0b101010; // `--` `++`: --foo; ++foo; // `--` `++`: foo--; foo++;
ES6 constは、データの不変性に関して何もしません。
では、不変の値を取得する方法は?
数値、文字列、ブール値、シンボル、null、未定義などのプリミティブデータ型は常に不変です。
var foo = 27; foo.bar = 42; console.log(foo.bar); // → `undefined`
データを不変にするには、 Object.freeze()を使用します。 このメソッドは、ES5から利用可能になりました。
const foo = Object.freeze({ 'bar': 27 }); foo.bar = 42; // TypeError exception strict mode; console.log(foo.bar); // → 27
ただし、Object.freeze()は表面的なもの、つまり 凍結されたオブジェクトには、ネストされたオブジェクトを変更する機能が引き続きあります。 MDNには、ディープフリーズの例であるdeepFreezeメソッドがあります。これにより、完全に不変のオブジェクトを作成できます。
Object.freeze()は、キーと値のオブジェクトでのみ機能します。現在、Date、Map、Setなどのオブジェクトを不変にする方法はありません。
将来のECMAScript標準用の不変データの提案があります。
const vs. させる
constとletの唯一の違いは、constは再割り当てが起こらないことを約束することです。
上記に基づいて、constはコードをより読みやすくします。 スコープ内では、constは常に同じオブジェクトを参照します。 letを使用すると、そのような保証はありません。 したがって、次のプラクティスに従う必要があります。
- 可能であれば、常にデフォルトでconstを使用してください。
- 再割り当てが必要なときに使用する
- varはまったく使用しないでください