JavaScript

ES6以降のJSの変数宣言とスコープ

前置き

ES6以降は可能な限りvarを使うのをやめてconstとletを使い分ける
基本constを使い、letは状態を書き換える場合につかう(ループカウンタなど)

var

var.js
var a = 1
console.log(a)
var a = 2
console.log(a)

function f(){
  var a = 3
  console.log(a)
  for(var a = 0; a < 10; ++a){
  }
  console.log(a)
}

f()
console.log(a)
結果
1
2
3
10
2
  • 関数スコープ
  • 再宣言可能
  • 上記特徴のためバグが出やすく、ES6以降はあまり使われない

let

let.js
let a = 1
console.log(a)
// error
// let a = 2
// console.log(a)

function f(){
  let a = 3
  console.log(a)
  for(let a = 0; a < 10; ++a){
  }
  console.log(a)
}

f()
console.log(a)
結果
1
3
3
1
  • ブロックスコープ
  • 再宣言不可能
  • 値の書き換え可能

const

const.js
const a = 1
console.log(a)
// error
// a = 2
// console.log(a)
// error
// const a = 2
// console.log(a)

function f(){
  const a = 3
  console.log(a)
// error
//  for(const a = 0; a < 10; ++a){
//  }
//  console.log(a)
}

f()
console.log(a)
結果
1
3
1
  • ブロックスコープ
  • 再宣言不可能
  • 値の書き換え不可能
  • ただしオブジェクトのプロパティや配列の追加削除は可能
const2.js
const obj = {}
const ary = []
obj.hoge = "huga"
ary.push("hoge")

オブジェクトの中身も書き換え不可にしたい場合

'use strict'
const obj = Object.freeze({})
obj.hoge = "aaaa"
console.log(obj)

ただし以下のケースは通ってしまう

'use strict'
const obj = Object.freeze({
  hoge : {}
})
obj.hoge.aaa = "aaaa"
console.log(obj)

上記ケースに困ったらimmutable.jsがある

https://facebook.github.io/immutable-js/