Backbone.js事始め その5 イベント処理


[前回の記事](http://qiita.com/tajihiro/items/c68d1579bf9e95d84116)で発見した記述ミスによる挙動の違いに気づいたので覚え書き。
モデルの初期化時にイベントを定義してみた。基本的には簡単な記述ミスであるのだが、全く違う挙動を見せるので下記にパターンを記す。

`on('change:name',function(){})`
`on('change :name',function(){})`
`on('change: name',function(){})`
`on('change : name',function(){})`

属性の`change`イベントをハンドラの定義する時に、`on('change:name',function(){})`と記述するわけであるが、思わずスペースを入れてしまうと挙動が異なる。一番の問題はエラーにならないので、非常に気付きにくい。

##ソースコード
```
	<script type="text/javascript">
	(function() {
		//----------
		// Model作成
		//----------
		var Person = Backbone.Model.extend({
			//Attribute(属性)
			defaults: {
				name: "None",
				age: 0
			},
			//コンストラクタ
			initialize: function(){
				console.log("初期化処理開始 : " + this.get("name"));
				//イベント定義
				this.on('change:name', function(){
			 		console.log("名前が変わりました。");
				}),
				this.on('change:age', function(){
			 		console.log("年齢が変わりました。");
				})
				console.log("初期化処理修了 : " + this.get("name"));
			}
		});
		//モデルのインスタンス化	
		var none = new Person();
		none.set('name','ほげほげ');
		//表示
		console.log("私は、" + none.get('name') + " " + none.get('age') + "歳です。");
		none.set('age',26);
		//表示
		console.log("私は、" + none.get('name') + " " + none.get('age') + "歳です。");
	})();
	</script>
```

##スペース無しの場合 ※正しい記述
```
//コンストラクタ
initialize: function(){
	console.log("初期化処理開始 : " + this.get("name"));
	//イベント定義
	this.on('change:name', function(){
 		console.log("名前が変わりました。");
	}),
	this.on('change:age', function(){
 		console.log("年齢が変わりました。");
	})
	console.log("初期化処理修了 : " + this.get("name"));
}
});
```
![スクリーンショット 2014-09-27 21.33.24.png](https://qiita-image-store.s3.amazonaws.com/0/3184/5d8c7fbf-cdc7-333f-b032-a38d8cc036b6.png "スクリーンショット 2014-09-27 21.33.24.png")


#スペース有り(前)の場合 ※記述ミス1
```
//コンストラクタ
initialize: function(){
	console.log("初期化処理開始 : " + this.get("name"));
	//イベント定義
	this.on('change :name', function(){
 		console.log("名前が変わりました。");
	}),
	this.on('change :age', function(){
 		console.log("年齢が変わりました。");
	})
	console.log("初期化処理修了 : " + this.get("name"));
}
});
```

![スクリーンショット 2014-09-27 21.36.30.png](https://qiita-image-store.s3.amazonaws.com/0/3184/78573d65-976f-7ca8-3e7d-0b61f27a92bf.png "スクリーンショット 2014-09-27 21.36.30.png")

#スペース有り(後)の場合 ※記述ミス2
```
//コンストラクタ
initialize: function(){
	console.log("初期化処理開始 : " + this.get("name"));
	//イベント定義
	this.on('change: name', function(){
 		console.log("名前が変わりました。");
	}),
	this.on('change: age', function(){
 		console.log("年齢が変わりました。");
	})
	console.log("初期化処理修了 : " + this.get("name"));
}
});
```

![スクリーンショット 2014-09-27 21.37.35.png](https://qiita-image-store.s3.amazonaws.com/0/3184/961a2b11-3987-1c86-cfcb-a419f5909495.png "スクリーンショット 2014-09-27 21.37.35.png")

#スペース有り(両側)の場合 ※記述ミス3
```
//コンストラクタ
initialize: function(){
	console.log("初期化処理開始 : " + this.get("name"));
	//イベント定義
	this.on('change : name', function(){
 		console.log("名前が変わりました。");
	}),
	this.on('change : age', function(){
 		console.log("年齢が変わりました。");
	})
	console.log("初期化処理修了 : " + this.get("name"));
}
});
```

![スクリーンショット 2014-09-27 21.38.35.png](https://qiita-image-store.s3.amazonaws.com/0/3184/b56275bc-0cb5-7585-de42-d46a66d3b759.png "スクリーンショット 2014-09-27 21.38.35.png")

##結論

まずは、記述ミス2の スペース有り(後)は、`change`チェンジハンドラに対して、スペース + 属性`: name`という属性を待ち受けていることになる。当然、そのような属性は存在しないために、そもそもイベントハンドラは呼ばれない。

次に、記述ミス1のスペース有り(前)と、記述ミス3のスペース有り(両方)の挙動は、チェンジ + スペース `change :`というハンドラを定義していることとなる。しかし、イベントハンドラが全て呼ばれてしまっている。これに関しては、どのような原理でそうなるのか正直わからない。

その挙動の仕組みをアドバイスを頂けたらと思うが、とりあえず記述ミスをしないようにすることを心に留める。