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

首先我用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对象就不会初始化,从而导致点击无效果。

简说一下coffeescript的constructor是如何导致Backbone.View的事件无法正常工作的.的更多相关文章

  1. vue添加滚动事件,解决简书Carol_笑一笑方案中vue移除滚动事件失效的问题

    在写项目的时候,遇到了需要添加滚动事件的问题,在简书Carol_笑一笑这里找到了解决方案.代码如下 <script> export default { name:"vue-scr ...

  2. Java Annotation 及几个常用开源项目注解原理简析

    PDF 版: Java Annotation.pdf, PPT 版:Java Annotation.pptx, Keynote 版:Java Annotation.key 一.Annotation 示 ...

  3. CoffeeScript简介 <二>

    集合与迭代 .. 与 ... 先看例子: arr = ["a1", "a2", "a3", "a4", "a5 ...

  4. 《大道至简》第一章读后感(java语言伪代码)

    中秋放假之际读了建民老师介绍的<大道至简>的第一章,其中以愚公移山的故事形象的介绍向介绍编程的精义.愚公的出现要远远早于计算机发展的历史,甚至早于一些西方国家的文明史.但是,这个故事许是我 ...

  5. CentOS安装使用.netcore极简教程(免费提供学习服务器)

    本文目标是指引从未使用过Linux的.Neter,如何在CentOS7上安装.Net Core环境,以及部署.Net Core应用. 仅针对CentOS,其它Linux系统类似,命令环节稍加调整: 需 ...

  6. React中类定义组件constructor 和super

    刚开始学习React没多久,在老师的教程里看到了类组件的使用示例,但是和资料上有些冲突,而引发了一些疑问: 类组件中到底要不要定义构造函数constructor()? super()里边到底要不要传入 ...

  7. Scala编程--函数式对象

    本章的重点在于定义函数式对象,也就是说,没有任何可变状态的对象的类.作为运行的例子,我们将创造若干把分数作为不可变对象建模的类的变体.在这过程中,我们会展示给你Scala面向对象编程的更多方面:类参数 ...

  8. Backbone框架浅析

    Backbone是前端mvc开发模式的框架.它能够让view和model相分离,让代码结构更清晰简答,开发进度加快,维护代码方便.但是,现在出了一种mvvm框架,它是下一代前端mvc开发模式的框架,代 ...

  9. AngularJS服务中serivce,factory,provider的区别

    Angular服务是一个由服务工厂创建的单例对象.这些服务工厂是由 service provider 依次创建的.而service providers是构造函数.它们必须包含一个$get属性用于在实例 ...

随机推荐

  1. MFC 在对话框显示图片的多种方法

      我们先从简单的开始吧.先分一个类: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) 为方便说明,我们已经建好一 ...

  2. Android菜鸟的成长笔记(9)——Intent与Intent Filter(下)

    原文:[置顶] Android菜鸟的成长笔记(9)——Intent与Intent Filter(下) 接着上一篇的内容,下面我们再来看看Intent的Data与Type属性. 一.Data属性与Typ ...

  3. go运算符

    package main import ( "fmt" ) func main() { fmt.Println(^) } -3 package main import ( &quo ...

  4. 更好的自动ssh登录

    更好的自动ssh登录 解决~/.ssh/known_hosts 过期问题. bash + expect bash:ssh.sh #!/bin/bash help(){ echo "usage ...

  5. 通过加载Kernel32来动态判断 当前操作系统32bit还是64bit

    工作原理:通过加载Kernel32来获取IsWow64Process 函数然后通过函数的地址操作,执行函数的操作. 在程序中只要我们获取了一个函数的地址,就可以找到正确的方法执行这个函数. 但是这种方 ...

  6. JavaScript面向对象编程(10)高速构建继承关系之对象拷贝

    前面的样例我们是通过构造器创建对象.而且希望该对象继承来自另外一个构造器的对象 我们也能够直接面向一个对象来达成继承的目的.使用下属步骤: 1.拷贝一个对象 2.给新对象加入属性 /** * 通过拷贝 ...

  7. 纠正一个概念:类就有VMT,各实例不过是共享这个VMT而已

    不是只有实例才有VMT,举个例子,各实例的VMT地址是相同的: Use System.Contnrs; procedure TForm1.BitBtn2Click(Sender: TObject); ...

  8. NYOJ 914 Yougth的最大化

    Yougth的最大化 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 Yougth如今有n个物品的重量和价值各自是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价 ...

  9. Unity3D游戏开发之开发游戏带来的问题

    昨日曾就某投资人把移动团队失败原因之中的一个归于选择Unity引擎进行了一番评论,工具本身无罪,但怎样理解工具.正确使用Unity引擎确实须要讨论,在选择Unity之前你也许须要了解下这个引擎实际开发 ...

  10. Servlet:通过初始参数实现权限访问某个文件、页面

    目录结构 src 目录下com.xieyuan包MyServlet.java文件(Servlet文件) package com.xieyuan; import java.awt.Color; impo ...