`

Ext源码解读之一 -- extend的实现

阅读更多
先看一个例子:
Gmis.ext.Animal = function() {
	this.run = function() {
		Gmis.util.printMessage("Animal run");
	};
	this.swim = function() {
		Gmis.util.printMessage("Animal swimming");
	};
	this.shout = function() {
		Gmis.util.printMessage("Animal shout");
	}
};

Gmis.ext.Cat = Ext.extend(Gmis.ext.Animal, {
			constructor : function() {
				Gmis.ext.Cat.superclass.constructor.call(this);
			},
			run : function() {
				Gmis.util.printMessage("Cat run");
			}
		});

var cat = new Gmis.ext.Cat();
cat.run();
cat.shout();

再看同样功能的第二个例子:
Gmis.ext.Animal = function(name) {
	this.name = name;
};
Gmis.ext.Animal.prototype = {
	run : function() {
		Gmis.util.printMessage(this.name + " 2Animal run");
	},
	swim : function() {
		Gmis.util.printMessage(this.name + " 2Animal swimming");
	},
	shout : function() {
		Gmis.util.printMessage(this.name + " 2Animal shout");
	}
};
Gmis.ext.Cat = function(name,age){
	Gmis.ext.Cat.superclass.constructor.call(this,name);
	this.age = age;
};

Ext.extend(Gmis.ext.Cat,Gmis.ext.Animal, {
			run : function() {
				Gmis.util.printMessage(this.name + " 2Cat run, age: " + this.age);
			}
		});

var cat = new Gmis.ext.Cat("jiafei",3);
cat.run();
cat.shout();


extend的源码:
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){
        if(typeof sp == 'object'){
        	//1、在我们的第一个例子中,会走这个分支的。
        	//实际上是把参数调整了下,overrides等于了第二个参数-字面量对象,
        	//	让sp等于了Gmis.ext.Animal,sb等于了字面量对象里的constructor(如果有的话)
        	//效果实际上跟第二个例子差不多。后边可以按照第二个例子讲解了
            overrides = sp;
            sp = sb;
            sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
        }
        //2、这个F的实例可就是子类原型哦
        var F = function(){},
            sbp,//子类的原型
            spp = sp.prototype;//超类的原型
        //3、F的原型等于了超类的原型    
        F.prototype = spp;
        //4、子类的原型等于了F的一个实例
        sbp = sb.prototype = new F();
        //5、子类原型的构造函数设置为了子类本身,如果不设置??
        sbp.constructor=sb;
        //6、子类的superclass属性等于了超类的原型,这样就可以直接调用子类.superclass.constructor.call(this,xxx)了
        sb.superclass=spp;
        //7、如果超类原型的构造函数等于Object对象原型的构造函数,这里还要顺便再设置下超类原型的构造函数。
        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;
        //8、把overrides里边的所有方法和字段全部拷到子类的原型中(记得是原型中),实际也是F对象的实例中
        Ext.override(sb, overrides);
        sb.extend = function(o){return Ext.extend(sb, o);};
        return sb;
    };
}(),//这里执行了哦,会返回一个function的

看下overrides:
override : function(origclass, overrides){
    if(overrides){
        var p = origclass.prototype;
        Ext.apply(p, overrides);
        if(Ext.isIE && overrides.hasOwnProperty('toString')){
            p.toString = overrides.toString;
        }
    }
}

extend用的是这里介绍的第6种--组合寄生模式。
分享到:
评论

相关推荐

    android-percent-support-extend源码

    "android-percent-support-extend" 源码项目是对此官方库的一个扩展,旨在提供更多的自定义功能和灵活性。这个源码库对于想要深入理解Android布局适配和优化的开发者来说,无疑是一份宝贵的学习资料。 首先,让我们...

    mongoose-schema-extend, mongoose架构继承和鉴别器密钥扩展.zip

    mongoose-schema-extend, mongoose架构继承和鉴别器密钥扩展 mongoose-schema-extend实现架构继承和可选鉴别器键,用于存储集合中不同类型的相关文档,并以正确的模型类型获取它们。通知从 0.2.1版本mongoose-schema...

    Laravel开发-laravel-schema-extend

    在Laravel框架中,数据库操作是非常重要的一部分,而`laravel-schema-extend`是一个扩展库,专门用于增强Laravel的数据库架构系统,特别是在处理MySQL数据库的"列注释"(column comment)和"表注释"(table comment...

    前端开源库-underscore-deep-extend

    这就是underscore-deep-extend存在的原因,它实现了深度复制,能够处理嵌套结构的合并。 首先,我们需要理解什么是深度扩展。深度扩展是一种对象合并的方式,它可以遍历并合并嵌套的对象和数组,不仅拷贝顶级属性,...

    【Prototype 1.4.0】源码解读----全文注释版

    【Prototype 1.4.0】是一个JavaScript框架,它的核心目标是简化动态Web开发,尤其强调面向对象的编程...尽管目前版本可能已更新至更高,但1.4.0版本的源码解读对于理解框架的设计理念和核心功能仍然具有很高的价值。

    前端开源库-html-webpack-random-extend-plugin

    "html-webpack-random-extend-plugin"就是一个这样的工具,专为HTML Webpack打包过程设计,其主要目标是实现HTML文件中引入的CDN资源路径的随机扩展,以达到缓存刷新的效果。 Webpack是一个强大的模块打包工具,它...

    Layui-select-extend-master.zip

    这个压缩包“Layui-select-extend-master”包含了所有必要的资源,包括CSS样式表、JavaScript源代码以及可能的示例文件。开发者可以根据自己的项目结构,将这些文件部署到合适的位置。 配置和初始化Layui-select-...

    cesium-extend_Extend_cesium拓展entity_cesium_

    Cesium是一个强大的开源JavaScript库,用于在Web上创建交互式的3D地球模型。"cesium-extend"项目是针对...在实际开发中,结合Cesium的文档和"cesium-extend"的API指南,可以灵活地实现各种定制化的3D地球应用场景。

    Django2.x与Vue2.x融合开发的Django-Vue-Extend项目源码

    项目概述:Django-Vue-Extend 本项目是一个融合了Django2.x和Vue2.x双技术栈的集成...简而言之,Django-Vue-Extend项目是基于Django2.x和Vue2.x的经典融合,旨在为开发者提供一个可扩展、易于维护的全栈开发解决方案。

    dva-model-extend:扩展dva模型的实用方法

    dva-model-extend 扩展dva模型的实用方法。安装npm install --save dva-model-extend用法import modelExtend from 'dva-model-extend' ;const human = { state : { stomach : null , } , reducers : { eat ( state ,...

    前端开源库-html-webpack-filter-extend-plugin

    这就是html-webpack-filter-extend-plugin的作用所在,它是一个用于扩展HTML Webpack插件功能的开源库,旨在帮助开发者更加灵活地处理HTML模板。 html-webpack-plugin是Webpack的一个常用插件,它能够自动将生成的...

    Laravel开发-laravel-exception-extend

    1. **克隆项目**:首先,你需要将 `laravel-exception-extend-master` 代码库克隆到你的 Laravel 项目的 vendor 目录下,或者使用 Composer 安装。 2. **配置**:根据项目文档配置新的异常处理器,可能需要修改 `...

    android-widget-extend

    各种控件组件展示。 支持API10+ 水平滑动listView。 异步加载图片。 双指缩放,拖动。 项目链接:https://github.com/gqjjqg/android-widget-extend

    EXT 实现省份--城市--地区--级连

    EXT,全称EXT JS,是一种基于JavaScript的开源富客户端框架,主要用于构建桌面Web应用程序。它提供了丰富的组件库,包括表格、表单...无论是从源码层面还是工具层面,EXT都是开发人员实现高效、美观Web应用的有力武器。

    前端开源库-class-extend

    `class-extend`库的核心就是提供了一种简便的方式来实现类的继承和扩展。 这个库的工作原理通常包括以下关键点: 1. **类的创建**:`class-extend`允许开发者定义基类(或称为父类)和子类。子类可以通过调用`...

    前端开源库-sand-extend

    总结来说,sand-extend作为一个优秀的前端开源库,它的出现极大地简化了JavaScript中的类继承和扩展,使得开发者可以更专注于业务逻辑,而无需担心底层的实现细节。在实际开发中,善用sand-extend能够提升代码质量,...

    前端开源库-aimee-extend

    在压缩包文件“aimee-extend-master”中,包含了库的源码和其他相关资源。开发者可以查看源码来深入学习其实现细节,也可以直接将库引入项目中进行实践。记得在使用开源库时,遵循开源许可证的规定,尊重作者的劳动...

Global site tag (gtag.js) - Google Analytics