ES6の新機能: 「let」「const」宣言を調べてみた

  • 118
    いいね
  • 2
    コメント

JavaScript はES6によっていろいろと機能が充実することになっているのですが、classとかgeneratorとかがよく取り上げられていると思っ立てたので、てっきりこれだけだと思ったのですよ。
まさか他にも機能があるとは。。。

というわけで、あまり話題に登っていないように見える新機能。。。というか新宣言について調べてみました
まさかの記事書きで年越すとは・・・

宣言が追加されてた!

JSの宣言文といえば、「var」しかなかったのですが、なんとES6にて、「let」「const」が追加されていたようです。
いまのところ、'use strict'を使わないと動きませんでした。

let ・・・ 「再宣言」が不可

まずは「let」宣言です。
こいつは端的にいうと、「再宣言ができない」宣言です。
簡単な例を以下に示しています。

'use strict'

var spam = 12;// 当然よろしい
var spam = 13;// これもオッケー

console.log(spam);//13

let ham = 15;//大丈夫
ham = 17;//問題なし

console.log(ham);

let ham = 12;//こいつはダメ

見てわかるように、「var」で宣言された変数は再宣言してもエラーを起こしません。
一方で、「let」で宣言された変数は値を代入しなおしても問題ありませんが、もう一度宣言することは許されていません。
「Identifier 'ham' has already been declared」というエラーメッセージが出てきます。

const ・・・ 「再宣言」も「再代入」も不可

次にconstですが、これは定数を意味しています。
つまり、「再宣言」どころか「再代入」やってはいけません。
以下にその例を示します。

'use strict'

var spam = 12;// 当然よろしい
spam = 13;// これもオッケー

console.log(spam);//13

const ham = 15;//問題なし

console.log(ham);

ham = 17;//だめ

これを動かすと、
「TypeError: Assignment to constant variable.」
というエラーが出てきます。

スコープ

let, constの宣言は、これ以外にスコープについても特徴を持っています。
以下のコードを見てみましょう

'use strict'

if (1) {
  var i = 10;
}

console.log(i);//10

if (1) {
  let j = 10;
}

console.log(j);// ReferenceError

if (1) {
  const k = 10;
}

console.log(k);// ReferenceError

let x = 11;
const y = 13;

if (1) {
  console.log(i);// 当然大丈夫
  console.log(x);// これは大丈夫
  console.log(y);// これも大丈夫
}

どうでしょうか。
「var」だと、if ブロックの中で宣言しても、その外で使えてしまいます。
ところが、「let」「const」宣言だと、ifブロックの中で宣言した変数・定数を、ブロックの外で使用することはできません。
これは他のブロックでも同じです。

オブジェクトと宣言

オブジェクトのconst宣言には少しだけ注意が必要です。

'use strict'

var a = {one: 1, two: 2};
a.one = 11;// OK
a = 1;// OK
console.log(a);

let b = {one: 1, two: 2};
b.one = 11;// OK
console.log(b);
b = 11;// OK
console.log(b);

const c = {one: 1, two: 2}
console.log(c);
c.one = 11;// OK
console.log(c);
c = 11;// これはエラー

例えconstで宣言していても、オブジェクトの要素に対しては変更を入れることが可能です。
変数の仕組み上、そうなるんでしょうが・・・もしかしたらハマるかもしれませんな

まとめ

というわけで、ES6で追加される宣言文「let」「const」について、一通り調べてみました。
どの宣言を使うかは場合によると思いますが、基本的にはconstを使うのが良さそうです。いや、NetBeansとか使っていると、PHPでも「値の再代入はバグのもとです」って警告貰うので。。。
ただし、分岐内で値の代入値が変わるようであれば、letを使うことになりそうです。
varは極力使わないほうが良いように思いました。

class定義の時どうなるかとかあるのですが、そのへんは長くなりそうなので、回を改めようと思います。

arrow関数について書きました
ES2015の新機能: 関数の新しい書き方「arrow 関数」

参考

https://medium.com/ecmascript-2015/let-const-35bca3b4a3c6#.17hlgzf8n
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/const
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/let
http://techblog.yahoo.co.jp/javascript/nodejs/Node-es6/