`
houfeng0923
  • 浏览: 145895 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

dojo类机制模拟实现

阅读更多

 

 

偶然在infoq上看到朋友的文章《dojo类机制简介》,闲来无事,根据文章所讲,做了个dojo类机制的模拟实现。

主要实现以下功能:

定义类、定义类静态变量、实现单继承和多继承、调用父类方法 以及工具类方法和属性(isInstanceOf方法和declaredClass)。

代码如下:

 

//dojo类机制模拟实现

//--------工具类-------------
//创建命名空间
function createNS(path){
   if(!path)return null;
	var r ;
	if(typeof path == 'string') r = path.split('.');
	else if(path.constructor==Array) r = path;
	var currentPath = window;
	for(var i=0;i<r.length;i++){
	   currentPath[r[i]] = currentPath[r[i]] || {};
	  	currentPath = currentPath[r[i]];
	}
	return currentPath;
}
//掺元继承
function mix(s,d){
	for(var i in s){
		if(s[i]&&s.hasOwnProperty&&s.hasOwnProperty(i)) d[i] = s[i];
	}
}
//类式继承
function extend(subclass,superclass){
    var F = function(){};/*在此使用一个空函数,并将用它创建的一个对象实例插入到原型链中,这样做可以避免创建超类的新实例.因为1.超类的示例可能会比较大2.超类的构造函数有一些副作用3.或者执行一些需要大量计算的任务*/
    F.prototype = superclass.prototype;
    subclass.prototype = new F();
    subclass.prototype.constructor = superclass;

    //为类和对象增加父类引用'superclass'
    subclass.prototype.superclass = subclass.superclass = superclass.prototype;
    //对使用“superclass.prototype={method1:function(){...},...}”方式定义的类进行构造器属性修正
    if(superclass.prototype.constructor==Object.prototype.constructor){
        superclass.prototype.constructor = superclass;
    }
}
//-----------------------------------------------
//类机制实现:声明类
function declareClass(path,parent,config){
   if(!path) return;
   var declaredClass = path;                 //类标记
   var pathAndName = path.split('.');        //分拆包名和类名
   var className = pathAndName.pop();        //获取类名
   var ns = createNS(pathAndName)||window;   //根据传入类路径,创建命名空间
   //声明类的实现
   var clz =function(){
      //如果存在父类,首先调用父类的构造器方法。
      if(clz.superclass&&clz.superclass.constructor) clz.superclass.constructor.apply(this,arguments);
      //如果config参数中设置了声明类的构造器constructor方法,调用声明类的构造器方法。
      if(config.constructor) config.constructor.apply(this,arguments);
   };

   if(parent){
   	if(typeof parent=='function'){
   	  	extend(clz,parent);
   	}else if(parent.constructor==Array){
      	//如果参数设置了多个父类,使用第一个作为声明类的父类,其他使用掺元继承方式实现。
         extend(clz,parent[0]);
         for(var i=1;i<parent.length;i++)
            mix(parent[i].prototype,clz.prototype);
   	}
   }
   //调用父类相关方法
   clz.prototype.inherited = function(args){
      var caller =  arguments.callee.caller;
      var methodName = caller.nom;
      return this.superclass[methodName].call(this,args);
   };
   //isInstanceOf方法
   clz.prototype.isInstanceOf = function(c){
   	return (this instanceof c);
   }
   //将config定义的属性赋予声明类
   for(var p in config){
   	clz.prototype[p] = config[p];
   	//如果属性为函数,为函数属性增加'nom'属性,值为函数名的字符串
   	if(typeof config[p] =='function') clz.prototype[p].nom = p.toString();
   }
   //增加declaredClass标记属性
   clz.prototype.declaredClass = declaredClass;
   //将声明类加入到命名空间
   ns[className] = clz;
}
 
 

测试代码:

//---------------测试---------------------
//定义cn.hou.GrandParent类
declareClass("cn.hou.GrandParent",null,{
   sex:'male',
   familyInfo:{money:1},      //静态属性
   constructor:function(param){
   	this.sex = param.sex;
   },
   getSex:function(){
   	return this.sex;
   }
});

var gp = new cn.hou.GrandParent({sex:'man'});
console.log(gp.getSex());              //man
gp.familyInfo.money++;
var gp2 = new cn.hou.GrandParent({sex:'woman'});
console.log(gp2.getSex());             //woman
console.log(gp2.familyInfo.money);     //2

//掺元测试类
function TestMix(){}
TestMix.prototype.test = function(){console.log('TestMix.test');};
//定义cn.hou.Parent子类,继承cn.hou.GrandParent 和 TextMix
declareClass("cn.hou.Parent",[cn.hou.GrandParent,TestMix],{
   name:null,
   age:0,
   constructor:function(param){
      this.name = param.name;
      this.age = param.age;
   },
   getName:function(){
   	return this.name;
   },
   getAge:function(){
   	return this.age;
   },
   getSex:function(){
      //var sex = this.superclass.getSex.apply(this);//在没有以上inherited方法前,调用父类同名函数 的一种方法。
      var sex = this.inherited(arguments);     //通过 declareClass 声明函数定义的对象,可以使用inherited方法调用父类同名函数。
   	return 'parent getSex() called:'+sex;
   }
});

var p = new cn.hou.Parent({name:'test',age:22,sex:'男'});
console.log(p.declaredClass);             //cn.hou.Parent
console.log(p.getName());                 //test
console.log(p.getSex());                  //parent getSex() called:男
console.log(p instanceof cn.hou.Parent)   //true
console.log(p.isInstanceOf(cn.hou.Parent))//true
console.log(p instanceof TestMix)         //false
p.test();                                 //TestMix.test
0
0
分享到:
评论

相关推荐

    DOJO详解(包括详细的例子)

    DOJO基于AMD(Asynchronous Module Definition)模块加载机制,这使得代码组织更加有序,便于维护和扩展。它还引入了dojo/_base,这是DOJO的基础模块,包含了基本的数据类型、事件处理和DOM操作等功能。 **2. 关键...

    dojo full frame demo

    在全屏模式下,Dojo能够帮助创建沉浸式用户体验,尤其适用于展示复杂的数据或进行桌面级应用程序模拟。 SpringBoot,另一方面,是Java后端开发的热门选择,以其快速启动和简化配置而著称。它内建了Spring框架的功能...

    AJAX的DOJO中文文档

    DOJO也支持通过xhr.form方法模拟HTML表单的提交。这个方法可以方便地将表单数据转换为请求参数,发送到服务器,同时处理响应。 8. **DOJO的Deferred对象** DOJO引入了 Deferred 对象,用于管理异步操作的回调链。...

    RFT识别疑难dojo对象自动化脚本

    这通常涉及到查找特定的DOM节点、识别Dojo特有的属性和CSS类,以及跟踪事件处理程序。 在编写自动化脚本时,有几点关键的技术需要掌握: 1. **定制识别规则**:由于RFT的标准识别机制可能无法很好地匹配Dojo对象,...

    火柴忍者Stickman Dojo 完整版.zip

    火柴人在空中翻滚、跳跃、攻击等行为都需要基于物理规则来模拟,比如碰撞检测、重力计算等。通过源码,我们可以学习到如何使用Box2D或自定义的物理引擎来实现这些功能,理解物理参数对游戏体验的影响。 再者,战斗...

    struts2简单模拟

    4. **编写Action类**:创建Action类,实现execute()方法,这是处理用户请求的入口。 5. **配置struts.xml**:配置Action及其对应的Result,定义请求路径和处理方法的映射。 6. **编写JSP页面**:创建视图页面,...

    struts2框架模拟-教学示范代码

    5. **插件支持**:Struts2有丰富的插件库,如Struts2-convention-plugin、Struts2-dojo-plugin等,这些插件可以简化配置,增强功能。 在“mvcch2”这个目录中,可能包含了Struts2 MVC实现的第二章内容,可能包括...

    javascript 框架

    它提供了多种实用工具函数,如自定义事件系统、异步I/O、模拟类和继承机制。MochiKit强调模块化和可测试性,使得代码更易于维护和扩展。 5. **MooTools 1.2.1**:MooTools是一款面向对象的JavaScript框架,它提供了...

    cpu-dojo:我们正在研究一系列工作中的小型道场,以便更多地了解 CPU

    - 源代码文件:包含实现CPU功能的Java代码,可能分为不同的类或模块,对应CPU的不同部分。 - 说明文档:解释项目的结构、目标和如何运行代码。 - 测试用例:用于验证代码正确性的输入和预期输出。 - 示例代码:演示...

    WebGIS从基础到开发实践代码(基于ArcGIS API for JavaScript)

    2.4.3模拟类与继承 2.4.4使用模块与包管理源代码 第3章页面布局设计 3.1使用布局小部件设计页面框架 3.1.1小部件与布局小部件简介 3.1.2使用面板组织页面元素 3.1.3使用容器小部件设计页面布局 3.2可移动的小部件微...

    java开发框架struts2

    5. **插件架构**:Struts2具有强大的插件扩展能力,例如,可以使用Tiles插件进行页面布局,Struts2-dojo插件集成Dojo库以实现丰富的客户端交互效果,或者Struts2-convention插件简化Action的配置。 6. **注解支持**...

    Struts2.2.3所有jar包

    Struts2拥有强大的插件系统,如Struts2-dojo-plugin提供了与Dojo库的集成,Struts2-convention-plugin则实现了基于命名约定的自动配置。 **9. 异常处理** Struts2提供了全局异常处理机制,可以统一处理应用程序中...

    北京圣思园张龙老师Struts2全部课堂笔记

    6. **插件体系**:Struts2具有强大的插件扩展能力,如Struts2-dojo-plugin用于集成Dojo库,Struts2-json-plugin支持JSON数据交换,增强了Web应用的交互性。 7. **异常处理**:Struts2提供了全局和局部的异常处理...

    Struts2 jar包

    8. **测试支持**: Struts2提供了测试工具和模拟环境,如Struts2 TestNG/JUnit Plugin,可以帮助开发者进行单元测试和集成测试,确保应用的质量。 综上所述,Struts2 jar包是构建Java web应用的强大工具,它通过模块...

    struts2工程包

    例如,你可以配置Action的名称、类路径、结果映射等,以实现请求和业务处理的映射。 3. **拦截器**:Struts2的拦截器机制是其强大之处,它允许在Action执行前后插入自定义的逻辑。拦截器可以用来进行权限检查、日志...

    web_os.rar_ WebOS_ajax web_ajax web os_web OS _webos

    Ajax引擎通常由JavaScript库(如jQuery、Prototype或Dojo)支持,实现异步请求和数据处理。 3. **应用程序框架**:WebOS可能包含一个或多个框架,用于简化开发和集成Web应用程序。这些框架可能提供了API和工具,...

    prototype.js

    3. **类和继承**:Prototype.js引入了模拟类的概念,并通过`Class.create`方法实现类的创建。同时,它使用`Object.extend`和`Prototype.inheritPrototype`实现了基于原型的继承,使得面向对象编程在JavaScript中变得...

    l-system:L型系统用于Clojure dojo

    它是由数学家 Aristid Lindenmayer 在1968年提出的,用于模拟生物形态的发展过程。L-系统通过一套简单的规则,即迭代和替换,可以产生复杂的几何形状,这在计算机图形学、数学和生物学中都有广泛的应用。 在Clojure...

    struts2中文教程

    6. **插件机制**:Struts2拥有丰富的插件库,如Struts2-dojo-plugin用于AJAX支持,Struts2-convention-plugin简化配置等。了解这些插件能提升开发效率。 7. **异常处理**:Struts2提供了一套完善的异常处理机制,...

    深入浅出struts2

    7. **插件机制**:Struts2拥有丰富的插件支持,如Tiles插件用于布局管理,Struts2-dojo-plugin提供Ajax功能,Struts2-json-plugin支持JSON数据交换等,这些插件极大地增强了Struts2的功能。 8. **国际化...

Global site tag (gtag.js) - Google Analytics