简说一下coffeescript的constructor是如何导致Backbone.View的事件无法正常工作的.
2013-07-05 22:51
381 查看
在继承方面,js还是弱项呀。发现在继承的时候constructor和initialize之分。网上文章没有说明二者关系。看了源码才发现二者的区别呀。
首先我用coffeescript来实现js的继承,过程中发现一个问题。
就是通过用Backbone来构造单页面程序的时候,如果父类或子类中定义了constructor而没有super。那么很高兴的告诉你,在子类注册的events是不工作滴。
这里提前告诉你是因为父类中如果没有super,择不会执行默认的构造器来构造Backbone.View类。而这个类在构造的时候工作是初始化类中的initialize和绑定events事件(基于Jquery的delegate)
不信你试试看。例如:
就是这样你在A中定义了constructor,而没有执行super,或者你在A中定义了construto且定义了super而在OA中的construtor构造中没有super。子类A中的events就没有执行。
根据这个一步步分析原因。
1:coffeescript在定义类中,如果类中没有构造constructor,则它会自己构造constructor。如果指定了constructor那么就会按照指定的来执行.
源码:
指定了constructor
未定义construto或定义并且super了
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对象就不会初始化,从而导致点击无效果。
首先我用coffeescript来实现js的继承,过程中发现一个问题。
就是通过用Backbone来构造单页面程序的时候,如果父类或子类中定义了constructor而没有super。那么很高兴的告诉你,在子类注册的events是不工作滴。
这里提前告诉你是因为父类中如果没有super,择不会执行默认的构造器来构造Backbone.View类。而这个类在构造的时候工作是初始化类中的initialize和绑定events事件(基于Jquery的delegate)
不信你试试看。例如:
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就没有执行。
根据这个一步步分析原因。
1:coffeescript在定义类中,如果类中没有构造constructor,则它会自己构造constructor。如果指定了constructor那么就会按照指定的来执行.
源码:
指定了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对象就不会初始化,从而导致点击无效果。
相关文章推荐
- 创新谈-如何处理DataGuard环境中万一网络失败将导致的Primary库短时间内无法正常工作的问题-张乐奕
- 基于WEB服务器导致消息中心各组件之间无法正常工作的问题分析与解决
- Android 设置了ClickableSpan导致的上层View点击事件无法响应解决方案
- 如何解决ViewPager在ScrollView中滑动经常失效、无法正常滑动问题。
- ListView的Item里的TextView设置ClickableSpan和LinkMovementMethod导致ListView无法响应点击事件
- Viewgroup被子VIew抢焦点,导致Item无法响应点击事件。
- 某数据库pmon进程无法正常工作导致宕机的事故
- mysql 崩溃导致无法正常工作
- NestedScrollView onClick事件不能正常工作
- android webview 因iframe+target=“_blank “ 导致的页面无法正常打开或获取不到跳转url
- 解决设备应用程序无法申请到内存,导致设备无法正常工作的问题---优化设备虚拟内存使用
- Windchill10.0升级到10.2版本导致Jersey-1.17无法正常工作的解决办法
- Jquery的事件绑定live方法在ios版的微信网站无法正常工作
- 如何解决由于服务过多或异常导致ArcGIS Server 无法正常运行的问题
- manifest文件导致,网狐无法正常工作问题.
- bashrc文件中环境变量配置错误,导致linux无法正常使用的解决方案
- 解决vi命令不正常退出导致.swp文件无法删除问题的梦幻之旅
- Ubuntu无法正常输入英文单引号符号 + 误删除package导致系统设置异常(解决方案)
- Sharepoint 2007 alertme (通知我) 无法正常工作
- Visual Studio 2005的JIT Debugger在Vista上面无法正常工作