各种Extend--Prototype,Ext,Jquery中Extend的比较


各种Extend--Prototype,Ext,Jquery中Extend的比较(一)

extend这个函数,在JS中,被赋予了各种神奇的功效,特别是在继承和各种对象操作中,起着很大的作用,
可以说,extend撑起了不少库的半边天,虽然有时它扮演的角色和作用不完全相同.

一.简单的类继承

刚开始接触extend函数,大家可能是在学习JS的继承的时候.为了简化派生子类的过程,这时神奇的extend出现了

1functionextend(subClass,superClass){
2//引入空函数,避免创建父类的新实例
3varF=function(){};
4F.prototype=superClass.prototype;
5//创建拷贝,不影响父类
6subClass.prototype=newF();
7//提供superClass属性,弱化父子类间耦合
8subClass.prototype.constructor = subClass;
9subCLass.superClass=superClass.prototype;
10if(superClass.prototype.constructor == Object.prototype.constructor){
11superClass.prototype.constructor=superClass;
12}
13}

这个函数,封装了继承中的细节,是实现类式继承,十分重要的部分,使用了一个F空函数作为过渡,可以避免
创建父类的实例.下面的代码更多是为了弱化代码耦合,可以使用superClass属性调用父类构造函数.

二.Prototype.js

接下来,最有可能接触的,必定是Prototype库的extend函数,曾经有大神说,离开extend函数,Prototype就无法成为Prototype了,可见extend函数对于Prototype的重要性.

在Prototype 1.3 框架中 给每个对象都定义了extend方法,

1//Prptotype库的extend,为Object类添加静态方法,
2Object.extend=function(destination,source) {
3for(propertyinsource) {
4destination[property]=source[property];
5}
6returndestination;
7}
8//通过Object类,为每个对象,添加方法
9Object.prototype.extend =function(object) {
10returnObject.extend.apply(this, [this, object]);
11}

第一个函数Object.extend,可以简单的理解为对象复制.目标对象将拥有源对象的所有属性和方法
第二个函数Object.prototype.extend,在prototype对象中加上一个extend函数,
其中精华语句Object.extend.apply(this, [this, object]); 将Object对象中的extend作为静态方法调用,
第一个参数this,指向调用对象本身,第二个参数,为一个数组,为调用对象本身和传递进来的对象参数object(一般为方法,下面有例子)

那么说了那么多.如何实现继承呢?Prototype是这样实现的

查看源代码
打印帮助
1//定义父类father
2function father(){
3}
4father.prototype={
5//各种方法
6}
7
8//定义子类son
9function son(){
10}
11
12son.prototype=(new father()).extend({
13//新添加方法
14....
15});

这样就实现了继承,先写这么多吧,其他两个框架,过几天再写.

各种Extend--Prototype,Ext,Jquery中Extend的比较(二)

Ok,继续各种 Extend--Prototype,Ext,Jquery中Extend的比较(一)文中所述,我将在接下来介绍 Ext js 中的继承和 Extend.

在接下去之前,再写写关于Prototype 1.3 的 extend ,将继承功能直接扩展在Object对象中,这样会污染了整个Object,对反射操作影响,后来作者果断在后续版本放弃对Object对象原型中扩展继承.

很多人(包括著名的JSON之父 D.C )就是诟病Prototype.js污染了原生对象的prototype和污染命名空间.虽然 Prototype.js 是个很优秀的框架,但是被 YUI , dojo , jQuery 不污染原型的框架联合打击,渐渐式微了..

曾经有很多优秀的库,都是基于 Prototype 的,例如用于 WebGIS 客户端的著名的OpenLayers,还有全世界最出名的特效库Script.aculo.us(可能撞墙).

Prototype 目前最新版本详情可以查看官网.

三.Ext JS的继承

接下来,说下本人刚开始是研究的框架 Ext JS.如果说 Jquery 是把锋利的小刀, YUI 是把无锋的重剑,另外 John Resig 和 N C.Zakas 关于两者的辩论,大家可以去围观下拔刺的翻译

那么基于 Yahoo-UI 的 Ext JS 可以说是一把厚重的大斧,主要用于企业应用系统的开发,属于应用级框架,基于组件级的 Ext js ,的确有它独特的特点,特别是它的UI界面,可以节省很多开发时间,再者由于 Ext 是高度基于面向对象的编程思想,封装性和扩展性也相当好.正是基于这两个特点,一个从来没有接触过Ext的初学者,可以直接从Demo中,学习和掌握这个框架的一本应用.但是,正是由于这个特点,对于想在 javascript 加深认识的初学者,这个框架不是一个很好的选择.

废话说完,下面回到正题.在剖析 extend 之前,先顺便介绍一下它的 apply 函数,这个函数实现了对象继承,注册在"Ext"的命名空间中,并放在了 Ext 类库的起始位置,可见它的重要性

1Ext.apply =function(o, c, defaults){
2//如果提供defaults对象,可以在复制父对象之前,实现自己方法和属性
3if(defaults){
4Ext.apply(o, defaults);
5}
6//反射复制
7if(o && c &&typeofc =='object'){
8for(varpinc){
9o[p] = c[p];
10}
11}
12returno;
13};

从上面代码可以看出 apply 有点类似 Prototype 的 Object.extend 做了个简单的对象复制,但是它扩展了一个功能,就是可以在复制之前,先添加自己的方法和属性,当然这个函数会覆盖原有的属性,如果要想不要覆盖可以使用 applyIf 函数.

1applyIf :function(o, c){
2if(o){
3for(varpinc){
4if(!Ext.isDefined(o[p])){
5o[p] = c[p];
6}
7}
8}
9returno;
10}

有对象继承,就肯定有类继承啦.接下来可以再看下 Ext.override 实现类继承

1/* @param {Object} origclass 要进行覆盖的类
2* @param {Object} 应该是一个包含一个或更多方法的对象字面量,将一系列的方法添加到origClass中
3* @method override
4*实现了将overrides,复制到origclass的prototype中去,从而实现了类继承.
5*/
6override :function(origclass, overrides){
7if(overrides){
8varp = origclass.prototype;
9Ext.apply(p, overrides);
10//河蟹IE的一个bug,IE9好像修复了.待验证
11if(Ext.isIE && overrides.hasOwnProperty('toString')){
12p.toString = overrides.toString;
13}
14}
15}

说了这么多,终于到了 extend 了吧!!果断上代码!!

1/* @param {Function} subclass 子类,
2* @param {Function} superclass 父类,
3* @param {Object} overrides 一些增加的方法和属性,将覆盖到子类中
4* @return {Function} 如果没有指定子类,将生成返回,反而,返回extended后的子类
5*/
6extend :function(){
7// 利用闭包,私有方法和私有对象,内部访问
8vario =function(o){
9for(varmino){
10this[m] = o[m];
11}
12};
13varoc = Object.prototype.constructor;//为后面生成子类构造函数的判断做准备
14
15//自执行函数,返回实际的extend函数内容
16returnfunction(sb, sp, overrides){
17//如果是两个参数,即sp为Object时
18if(Ext.isObject(sp)){
19overrides = sp;
20sp = sb;
21//如果overrides的构造函数是Object,生成子类的构造函数,即可以在overrides携带构造函数,
22//后面有例子加以说明
23sb = overrides.constructor != oc ? overrides.constructor :function(){sp.apply(this, arguments);};
24}
25//空函数,避免修改父类的prototype
26varF =function(){},
27sbp,
28spp = sp.prototype;
29
30F.prototype = spp;
31//原型继承,如果无法理解可见本系列的上一篇文章
32sbp = sb.prototype =newF();
33//修改子类的prototype的构造函数指向子类构造函数
34sbp.constructor=sb;
35//指定子类的superclass为父类的prototype
36sb.superclass=spp;
37//将父类的prototype的构造函数指向父类构造函数
38if(spp.constructor == oc){
39spp.constructor=sp;
40}
41//为子类注册一个静态方法override
42sb.override =function(o){
43Ext.override(sb, o);
44};
45//指定子类的prototype的superclass属性为父类的prototype
46sbp.superclass = sbp.supr = (function(){
47returnspp;
48});
49//指定子类的prototype的override
50sbp.override = io;
51//将overrides所有方法和属性复制到子类中
52Ext.override(sb, overrides);
53//为子类注册一个静态方法extend
54sb.extend =function(o){returnExt.extend(sb, o);};
55returnsb;
56};
57}()

实践才是硬道理!!下面上"栗子"!!

1//第一种
2varSonClass=Ext.extend(FatherClass,{/*各种房子,美女,豪车,任你添加*/});
3//第二种
4varSonClass=Ext.extend(FatherClass,{constructor:function(){/*构建子类*/}});
5//第三种
6varSonClass=function(config){
7SonClass.superclass.constructor.call(this,config);
8}
9Ext.extend(SonClass,FatherClass,{/**/});

由此可见,Ext的继承是在(一)中提到了简单继承发展起来的,并实现了更加强大的功能,支持完美的对象继承,类继承,生成子类继承,十分灵活,Ext在 extend 和 apply 和 override 三大的函数的配合下,完美实现了JS继承,为整个Extjs的面向对象和组件级应用打下了坚实的基础.

到此,Ext的extend已经解析完毕,真长啊,大家拍砖抓紧

以上源码分析基于 Ext js 3.1 目前最新版本请链接官网

优质内容筛选与推荐>>
1、MySQL之数据类型与操作数据表
2、UVA 11059 Maximum Product(枚举start+end)
3、炫酷的console
4、在C# WinForm TextBox实现联想输入(suggest)和历史记录输入
5、ajax问题


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn