简说一下coffeescript的constructor是如何致使Backbone.View的事件没法正常工做的.

 

在继承方面,js仍是弱项呀。发如今继承的时候constructor和initialize之分。网上文章没有说明两者关系。看了源码才发现两者的区别呀。javascript

 

首先我用coffeescript来实现js的继承,过程当中发现一个问题。java

就是经过用Backbone来构造单页面程序的时候,若是父类或子类中定义了constructor而没有super。那么很高兴的告诉你,在子类注册的events是不工做滴。app

这里提早告诉你是由于父类中若是没有super,择不会执行默认的构造器来构造Backbone.View类。而这个类在构造的时候工做是初始化类中的initialize和绑定events事件(基于Jquery的delegate)函数

不信你试试看。例如:this

class OA extends Backbone.View
	constructor:->
		#super;
		console.log "OA constructor";
	initialize :->
		console.log "OA init";
class A extends OA
	constructor:->
		#super;
		console.log "A constructor";
	initialize:->
		console.log "A init";
	events : 
		"click #btn1" : "btnClick"
	btnClick : ->
		console.log "btn click 1";

就是这样你在A中定义了constructor,而没有执行super,或者你在A中定义了construto且定义了super而在OA中的construtor构造中没有super。子类A中的events就没有执行。spa

根据这个一步步分析缘由。prototype

1:coffeescript在定义类中,若是类中没有构造constructor,则它会本身构造constructor。若是指定了constructor那么就会按照指定的来执行.code

源码:对象

指定了constructor继承

OA = (function(){
	function e(){console.log("OA constructor")}
})(Backbone.View)

未定义construto或定义而且super了

__extend = function(t,n){
	function i(){
		this.constructor = t;
	}
	for(var r in n) e.call(n,r) && (t[r]=n[r]);
	i.prototype = n.prototype;
	t.prototype = new i;
	t.__super__ = n.prototype;
	return t;
}
OA = (function(n){
	function e(){
		console.log("OA constructor")
		_ref = e.__super__.constructor.apply(this,arguments);//这个等价于Backbone.View.prototype.constructor.apply(this,arguments);
	}
	__extend(e,n);//这个是用来继承的。
})(Backbone.View)

 

ok刨到这里还得继续往祖坟刨,看下这个源码再解释。

Backbone.View不用说。上面就几个属性和方法。能够看到为何类定义了initialize后自动调用的缘由了吧。

还有你也知道为何view中events定义后就能够处理事件了吧(由于delegateEvents初始化了)。

这是部分代码,若是有js高级教程经验的能够看下backbone.js关于view类的源码。


Backbone.View.prototype是经过underscore的extend继承Events和opt拓展属性组合而成的(若是不懂underscore.js的extend请看这里:http://underscorejs.org/#extend)。View.prototype==Backbone.View由于function是引用调用,公用一片内存,

因此View.prototype的变化会影响到Backbone.View的prototype.

再看e.__super == Backbone.View.prototype以后Backbone.View.prototype.constructor就是由Backbone.View的构造的,因此e.__super__.constructor则就是Backbone.View.apply(this,arguments);因此执行Backbone.View就有了一些关于事件,initialize函数的一些初始化。在类中若是super了。就会执行parent的constructor。直到执行继承Backbone.View的constructor便可。

不知道你们明白了与否。

也就是super执行的流程以下:

child(constructor)->parent(constructor).......//若是constructor中有super.就是这个执行顺序。只要继承类中某个类没有super。择constructor就中止了构造。

ok,到了这里,我想大概都应该明白了。因此若是之后涉及到继承。请谨慎定义constructor。若是你须要在子类中定义事件,而有继承了父类。那你必定要检查一下父类的constructor和子类的constructor是否super了(coffee中的super就是调用父类的构造函数,然-child.__super__.constructor.apply(this,arguments)).不然你子类的events对象就不会初始化,从而致使点击无效果。

相关文章
相关标签/搜索