JavaScript
es6

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

More than 1 year has passed since last update.

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/