`
houfeng0923
  • 浏览: 144807 次
  • 性别: 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的不同部分。 - 说明文档:解释项目的结构、目标和如何运行代码。 - 测试用例:用于验证代码正确性的输入和预期输出。 - 示例代码:演示...

    Web GIS从基础到开发实践 基于ArcGIS API for JavaScript

    2.2.2ArcGIS API for JavaScript与Dojo的关系 2.3开发与调试工具 2.3.1集成开发环境 2.3.2调试工具 2.3.3Firebug 2.3.4其他工具软件 2.4Dojo基础知识 2.4.1JavaScript对象 2.4.2函数也是对象 2.4.3模拟类与继承 ...

    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提供了一套完善的异常处理机制,...

Global site tag (gtag.js) - Google Analytics