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/