`
houfeng0923
  • 浏览: 142679 次
  • 性别: 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类机制幕后的知识,其中会涉及到dojo类机制的实现原理并对一些关键方法进行源码分析,当然在此之前希望您能够对JavaScript和dojo的使用有些基本的了解。

    dojo的包加载机制

    dojo的包加载机制, 源代码中加了注释和debug,只供大家参考

    dojo enhancedGrid pagination 分页实现

    利用dojo的enhancedGrid实现分页,利用静态数据加载和json文件方式分别加载,也利用XHR方式获取json文件数据生成grid,另外利用fetch实现分页的过滤、排序等功能。

    dojo dojo实例 dojo例子 dojo资料 dojo项目 dojo实战 dojo模块 dojo编程

    dojo dojo实例 dojo例子 dojo资料 dojo项目 dojo实战 dojo模块 dojo编程

    AJAX之Dojo实现登陆框

    AJAX之Dojo实现登陆框

    DOJO TableContainer实现表单布局.js

    DOJO TableContainer实现表单布局.js

    DOJO 学习笔记 dojo

    一、 Dojo学习笔记(1. 模块与包) 1 二、 Dojo学习笔记(2. djConfig解说) 4 三、 Dojo学习笔记(3. Dojo的基础对象和方法) 6 四、 Dojo学习笔记(4. dojo.string & dojo.lang) 9 五、 Dojo学习笔记(5. dojo.lang.array ...

    dojo文档 dojo文档 dojo文档

    dojo文档 dojo文档 dojo文档 dojo文档 dojo文档 dojo文档 dojo文档 dojo文档 dojo文档 dojo文档 dojo文档 dojo文档

    dojo实现登陆框架

    dojo 实现登陆框架 浪曦的那个谁讲的我忘了饿

    dojo js dojo js

    dojo js dojo js dojo js dojo js dojo js dojo js dojo js

    dojo是JavaScript语言实现的开源DHTML工具

    Dojo是一个用JavaScript语言实现的开源DHTML工具包。它是在几个项目捐助基础上建立起来的(nWidgets, Burstlib, f(m)),这也是为什么叫它a unified toolkit的原因。Dojo的目标是解决开发DHTML应用程序遇到的那些、...

    DOJO中文手册【出自dojo中国】

    Dojo 是一个用javascript语言实现的开源DHTML工具包。它是在几个项目捐助基础上建立起来的(nWidgets, Burstlib, f(m)), 这也是为什么叫它a \"unified\" toolkit的原因。Dojo的目标是解决开发DHTML应用程序遇到的那些...

    精通Dojo by Dojo之父

    Dojo是一个非常强大的、面向对象的、开源的JavaScript工具箱,它为开发富客户端Ajax应用提供了一套完整的小部件和一些特效操作。曾经有人这样说:“对于一个Web开发者而言,如果没有Dojo,他将是一个“残废”的...

    定义自己的dojo组件类

    该文档教大家如何定义自己的dojo组件类,并在程序中如何引用

    dojo精品中文教程(包一)

    很不错的中文教程!文件太大分3个包! 目录如下: dojo精品中文教程 Dojo.1.0 Practice Note [1] 什么是dojo 选择dojo的理由 AJAX架构之Dojo篇 Adding Ajax中文版 (DoJo) ...利用Dojo实现拖动(Drag and Drop)效果

    dojo入门系列教程.rar

    dojo入门系列教程,包含入门简介,在javascript基础上介绍dojo的语法特色,ajax的dojo包装---xhr框架的编程要点, Dojo 事件机制.以及对dojo最具特色的web UI设计的全面介绍.

    dojo精品中文教程(全)

    分三个包上传时,第三个包好像传不上去,我给整合了一下,打在一个包里上传了! dojo精品中文教程 Dojo.1.0 Practice Note [1] 什么是dojo 选择dojo的理由 ...利用Dojo实现拖动(Drag and Drop)效果

    javascript dojo

    学习dojo的绝好资源学习dojo的绝好资源学习dojo的绝好资源学习dojo的绝好资源学习dojo的绝好资源学习dojo的绝好资源学习dojo的绝好资源学习dojo的绝好资源学习dojo的绝好资源学习dojo的绝好资源学习dojo的绝好资源...

    Dojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库

    dojo.js.核心jsDojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库

    struts2+dojo实现例子

    struts2+dojo ajax实现小例子,部署后可直接使用,可供学习和参考。

Global site tag (gtag.js) - Google Analytics