Ext.extend 源码分析
来源:互联网 发布:nuance待遇 知乎 编辑:程序博客网 时间:2024/05/16 00:40
在Ext.extend中混合使用了两种继承手段:原型集成和对象冒充。
原型集成主要表现在:
var F = function(){}, sbp, spp = sp.prototype; F.prototype = spp; sbp = sb.prototype = new F(); //将子函数sb的构造函数指回去 sbp.constructor=sb;
对象冒充主要表现在:1、var Person = Ext.extend(Animal, {...});或者 var Person = Ext.extend(Animal, {constructor: function(){....}};情况调用下的:
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};2、Person = function(){
Person.superclass.constructor.call(this, {....});
};
Ext.extend(Person, Animal, {...});
上面只是简单的对Ext.extend的实现做了简单的描述,如果不明白,请看下面对源码的详细解析,如果哪位觉得有更好的解释或者不对的地方,欢迎批评指正
//在本方法中使用了闭包以及自执行,当浏览器加载js时就会执行该函数,然后将return的对象返回出来 extend : function(){ // inline overrides //私有变量,对外不可调用 var io = function(o){ for(var m in o){ this[m] = o[m]; } }; var oc = Object.prototype.constructor; return function(sb, sp, overrides){ /** * 主要用做移位,例如以下两种写法: * 1、var Person = Ext.extend(Animal, { * name: 'huang', *//如果子类提供了自己的构造方法,则使用自己提供的构造方法(overrides.constructor), *//否则则使用则会赋值给一个函数:function(){sp.apply(this, arguments); *//如果子类没有提供自己的构造方法,使用apply调用父类的构造函数,将父类中通过this赋值的属性继承下来, *//但是父类的prototype上的属性不会被继承下来(对象冒充),对于父类静态的属性不会被继承下来 * constructor: function(){...} * }); * 2、Ext.extend(Person, Animal, {...}); * * 如果使用第二种方式那么if条件肯定是不成立的,也就不会给子类设置一个默认的构造函数,而是使用我们自己提供的构造函数Person进行 * 对象的构造,正因为如此,此时也享受不到Ext默认插入的这句调用:sp.apply(this, arguments);所以需要获得父类的实例属性和方法, * 需要在构造函数中手动加入对象的冒充操作:Person.superclass.constructor.call(this, config); */ if(Ext.isObject(sp)){ overrides = sp; sp = sb; sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; } /** * 这里的亮点是空函数,因为空函数里面没有通过this进行赋值的属性,因此将sp.prototype 赋值给F.prototype * 然后将new F()赋值给sb.prototype,保证了sbp的纯净性 */ var F = function(){}, sbp, spp = sp.prototype; F.prototype = spp; sbp = sb.prototype = new F(); //将子函数sb的构造函数指回去 sbp.constructor=sb; /** * 给子函数sb赋属性superclass,并指向sp.prototype,自定义一个属性来记录子类的父类是什么 * 这样就可以直接调用 sb.superclass.constructor.call(this, xxx)了; */ sb.superclass=spp; /** * 这是一个容错处理,防止父类的构造函数没有指正确, * 这里也是主要为了在子类中调用sb.superclass.constructor.call(this, xxx)做准备 * 例如:Animal = function(cfg){ *this.name = "dog"; *Ext.apply(this, cfg); *} *Animal.prototype = { *eat: function(){ *alert("animal eat"); *} *} *//如果下面这一句没有写,spp.constructor 就会指向一个object * Animal.prototype.constructor = Animal; */ if(spp.constructor == oc){ spp.constructor=sp; } sb.override = function(o){ Ext.override(sb, o); }; sbp.superclass = sbp.supr = (function(){ return spp; }); sbp.override = io; /** * 此处将overrides上的属性全都copy到了sb.prototype上,因此如下面的写法: * Animal = function(){ * this.name = "dog"; * } * Animal.prototype = {...}; * Person = function(){ * this.sex = "boy"; * } * Ext.extends(Person, Animal, { * name: "kk" * }); * var p = new Person(); * p.alert(p.name); * 这样写也出来的结果是:dog,而不是kk,因为name:kk在prototype上,原型查找机制,对象上直接有的属性优先 * 而如果var p = new Person({name: 'huang'});执行结果则是:huang */ Ext.override(sb, overrides); sb.extend = function(o){Ext.extend(sb, o);}; return sb; }; }(), override : function(origclass, overrides){ if(overrides){ var p = origclass.prototype; Ext.apply(p, overrides); if(Ext.isIE && overrides.toString != origclass.toString){ p.toString = overrides.toString; } } },
- Ext.extend 源码分析
- Ext源码分析源码分析之Ext的继承模式解说——第三节、分析Ext.extend
- 关于Ext.extend源码学习
- jquery.extend源码分析
- Query源码分析-----$.extend
- jQuery源码分析-extend函数
- jQuery中extend()源码分析
- 主题:《仔仔细细分析Ext》 第一章 必须理解Ext.extend函数
- 转载:《仔仔细细分析Ext》 第一章 必须理解Ext.extend函数
- 《仔仔细细分析Ext》 第一章 必须理解Ext.extend函数 [转]
- 《仔仔细细分析Ext》 第一章 必须理解Ext.extend函数 [转]
- Ext.extend()
- Ext.extend
- jquery源码分析之扩展函数 extend, $.extend
- jQuery.extend()方法和jQuery.fn.extend()方法源码分析
- .Ext源码解读之一 -- extend的实现
- jQuery源码分析10: jQuery.extend
- 【jQuery-1.7.2源码分析】extend
- poj 楼天成的男人八题系列 A New Stone Game 博弈问题
- 转换数据库时间字段格式函数
- 程序的悟透
- 千山独行-一个人的创业路(连载三)
- Android软件开发之 自定义别样Toast
- Ext.extend 源码分析
- 学习笔记
- 64位win7下安装oracle的一些问题
- 面试常见智力题解答
- SD_STM32_SPI驱动+FatFs文件系统
- 最长公共子串
- 直接改变chm文件的字体大小
- poi
- java网络通信编程