Fork me on GitHub

backbone的extend(0.9.2)

0.9.2版  原创,转载请标明 3Q....

1 var AppView = Backbone.View.extend({
2 
3 
4 
5 })
6 
7 console.log(AppView)

AppView是 Backbone.View 的一个视图模型子类,即AppView是父类返回的一个新的构造函数

源代码如下:

  var extend = function(protoProps, staticProps) {
    var parent = this;
    var child;

    if (protoProps && protoProps.hasOwnProperty('constructor')) {
      child = protoProps.constructor;
    } else {
      child = function(){ parent.apply(this, arguments); };
    }

    _.extend(child, parent);

    ctor.prototype = parent.prototype;
    child.prototype = new ctor();

    if (protoProps) _.extend(child.prototype, protoProps);

    if (staticProps) _.extend(child, staticProps);

    child.prototype.constructor = child;

    child.__super__ = parent.prototype;

    return child;
  };

  Model.extend = Collection.extend = Router.extend = View.extend = extend;

以上代码其实就是JS的原型继承,无非就是把 静态方法 与 原型方法克隆到 一个新的对象上

具体:

extend 函数中定义了3个参数

this 代表父类  parent

protoProps 实例属性

staticProps 静态属性

就上面例子而言就是 parent就是Backbone.ModelprotoProps 是传进去的{}对象,staticProps 还木定义

 

 1    /**
 2      * 辅助工具
 3      * **/
 4 
 5     //共享空构造函数来帮助创建原型链。代理模式
 6     var ctor = function () {
 7     };
 8 
 9 // Helper function to correctly set up the prototype chain, for subclasses.
10 // Similar to `goog.inherits`, but uses a hash of prototype properties and
11 // class properties to be extended.
12     //parent, protoProps, staticProps
13     //父类,实例属性,静态属性
14     var inherits = function (parent, protoProps, staticProps) {
15         //构造的实例对象
16         var child;
17 
18         //判断protoProps是否一个原型对象(prototype),如果是则将child赋值为原型对象所属的构造函数
19         if (protoProps && protoProps.hasOwnProperty('constructor')) {
20             child = protoProps.constructor;
21         } else {
22             //当子类没有提供特定的constructor的时候,应该调用父类的。
23             /**
24              * 否则将新建一个构造函数赋值给child
25              * child = function () {}其实是要在new的时候才会
26              * 调用的,所以我们先假设我们设置的字段里面没有constructor,
27              * 所以当我们通过var temptA = new Tempt()的时候,
28              * 调用的是function () {Model.apply(temptA, arguments)},
29              * **/
30             child = function () {
31                 //inherits函数返回的是一个构造函数,我们会用new child()来调用此构造函数
32                 //(例如:AppView = Backbone.View.extend({});var appView=new AppView();),
33                 // 所以此处的this指向我们new的实例(例如var appView=new AppView(),则this指向appView)
34                 //new AppView进行的操作其实是Backbone.Model.apply(this,arguments) ,
35                 // 也就是说我们实例化appView的时候其实是调用Backbone.Model
36 
37                 //实例对象调用Backbone.Model
38                 parent.apply(this, arguments);
39             };
40         }
41 
42         //复制静态属性parent -> child ,模型的属性复制给实例对象
43         _.extend(child, parent);
44 
45         /**代理继承
46          * proxy来实现继承,这样就避免了在classical继承中出现的parent的constructor被使用两次带来
47          * 的效率问题和在原型链中再次继承this的属性
48          *  function obj (o){
49          *      var f = {}
50          *      f.prototype = o
51          *      return new f();
52          *  }
53          */
54             //ctor是一个内容为空的构造函数,此处将其原型对象设置为Backbone.View.prototype
55         ctor.prototype = parent.prototype;
56         //将child的原型对象设置为一个ctor的实例,child.prototype.contructor指向ctor
57         child.prototype = new ctor();
58 
59         /**
60          * 给新的类指定实例属性和静态属性的功能
61          * **/
62         //将Backbone.View.extend的第二个参数(一般是一个对象)的的所有属性复制到child.prototype
63         if (protoProps) _.extend(child.prototype, protoProps);
64 
65         //将Backbone.View.extend的第三个参数(一般是一个对象)的的所有属性复制到child,也就是给child设置静态属性或方法
66         if (staticProps) _.extend(child, staticProps);
67 
68         //执行完child.prototype=new ctor后,child.prototype.constructor已经不指向child,所以此处需要显示设置
69         child.prototype.constructor = child;
70 
71         //EcmaScript中并没有定义__super__这个属性,此处应该是backbone记录child对应的super类
72         child.__super__ = parent.prototype;
73 
74         return child;
75 
76         /**
77          *  new 自定义View等() 所属类--> child(用户创造的构造函数)
78          *  原型对象--> ctor的一个实例(我们自定义的一些函数和方法都设置到此实例上)
79          *  原型对象--> Backbon.View.prototype
80          * **/
81     };

 

 

 

 

 

 

 

posted on 2012-08-26 07:29  【艾伦】  阅读(2117)  评论(1编辑  收藏  举报