More than 1 year has passed since last update.

参照型(※)は初期値にしない

JavaScriptでクラス(ライクなオブジェクト)を作る時、インスタンスプロパティに配列やハッシュ(のようなオブジェクト)を設計することはよくやると思います。

そんな時注意しなければならないのが、参照型(※)の値は初期値として設定しないということ。

CoffeeScriptの場合


# ダメなパターン
class Foo  
  array: []
  object: {}

foo = new Foo
foo2 = new Foo

foo.array.push 'オラァ'
foo.object.a = '無駄ァ'

# foo に設定したはずが foo2 にも影響する
console.log foo2.array[0] # => 'オラァ'
console.log foo2.object.a # => '無駄ァ'


# 大丈夫なパターン
class Bar
  array: null # 初期値はnull
  object: null # 初期値はnull
  constructor: ->
    @array = [] # 本当に利用したい初期値を設定
    @object = {} # 本当に利用したい初期値を設定

bar = new Bar
bar2 = new Bar

bar.array.push 'オラァ'
bar.object.a = '無駄ァ'

# 影響しない
console.log bar2.array[0] # => undefined
console.log bar2.object.a # => undefined

JavaScriptではつまりこういうこと


// ダメなパターン
function Foo () {}
Foo.prototype.array = [];
Foo.prototype.object = {};

// 大丈夫なパターン
function Bar () {
  this.array = [];
  this.object = {};
}
Bar.prototype.array = null;
Bar.prototype.object = null;

なぜこうなるの?

それは君「プロトタイプチェーン」だよ!

プロトタイプチェーンとは

ここで説明するには奥が深すぎるので、説明しません!以下など参照にしてください。

や...やっと理解できた!JavaScriptのプロトタイプチェーン

実はnullと設定する必要はないのでは?

基本的にそのとおりです。

ただ、Coffeeの場合など"明示的"にプロパティの宣言をしたいので先のような記述にしています。

コンストラクタ内で設定するというガイドラインもあっても問題ないと思います。

※参照型について

値をざっくり分類すると

基本型

  • 論理値
  • 数値
  • 文字列
  • null
  • undefined

参照型

  • 配列
  • オブジェクト
  • 関数 などなど

性質などはこれも今更ここで説明することでもないので割愛。

ちなみにオブジェクトの参照型扱いについて以下を参照してください。

誤り : JavaScript のオブジェクト型は参照型ではないというお話


詳しい説明は全くしませんでしたが、つまりそういうことなので覚えておきましょう。