`
javeejy
  • 浏览: 6327 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Javascript实现类继承特性的另一种方法

阅读更多

 

  转自:http://www.bgscript.com - 背光脚本

 

类的继承特性可以有效的重用源代码,提高开发效率.

在WEB开发中,无论是富客端页面还是一般的网页, 可重用的地方都很多, 通过Javascript以对象方式来组织这些重用代码结构清晰,易于维护与扩展,复用类可以减

 

少JS文本体积,加快下载速度.

但Javascript语言本身并不提供面向对象(封装,多态,继承)的原生支持,具体还得手动设计.

设计方式很多,但原理都是复制对象属性产生新类,通过apply或call方法调用父类方法.

例如,

 

> Ext库:

 

在类声明时为

Ext.CurrentClass = Ext.extend(Ext.SuperClass, { ... });

 

在设计类中调用父类初始化方法为

 

Ext.CurrentClass.superclass.initComponent.call(this);

 

> jQuery:

 

在类声明时为

$.widget("ui.currentclass",{ ... });

 

在设计类中调用父类初始化方法更为显式

$.widget.prototype. initComponent.apply(this, arguments);

 

以上实现方式或多或少有些冗长, 根据笔者经验,有一种更好的方法, 

 

例如 :

 

  var MyClass = CC.create(SuperClass, function(superclass){
      
      return {
        initComponent : function(options) {
           superclass.initComponent.call(this, options);
           // other codes... 
       }
      };
  });

 

 

 

 

这种方式有它的优点:

  构建够直观,简洁. 它是将整个类包装在一起的,浑然一体,像Java类一样, 父子关系明了.

  父类访问方便, 快速. 该方法把父类作为参数superclass传进来构建,子类方法通过JS闭包特性直接引用, 快速高效.子类方法中完全不必知道父类是谁.

  类可以共享一些其它类没有的东西, 如变量, 方法等, 这有点像Java中类的static成员.

 

实现方法如下

做些前奏准备,写一个99.99%的JS库都会有的方法

 

//
//对象属性复制方法,很多库都有实现,如PrototypeJS里面的extend和Ext里面的Ext.apply
//
function extend(des, src) {
  if (!des)
    des = {};
    
  if (src) {
    for (var i in src) {
    	des[i] = src[i];
    }
  }
  
  return des;
}

 

再定个对象,名称任意,主要是挂个方法而已,这里简单起见写为CC.

 

var CC = {};

 

以下是实现主要函数,主要是组装返回要的对象.

 

//
//create 用于创建类
//
CC.create = function(superclass, constructor){
   var clazz = (function() {
      this.initialize.apply(this, arguments);
   });
	
	//如果无参数,直接返回类.
	if(arguments.length == 0)
    return clazz;
  
  //如果无父类,此时constructor应该为一个纯对象,直接复制属性返回.
  if(!superclass){
  	extend(clazz.prototype, constructor);
  	return clazz;
  }
  
  var absObj = clazz.prototype, 
      sprPropty = superclass.prototype;

  if(sprPropty){
			//用于访问父类方法
      clazz.superclass = sprPropty;
      extend(absObj, sprPropty);
      
      //调用属性构造函数创建属性,这个是实现关键.
      extend(absObj, constructor(sprPropty));

      // 子类实例直接通过obj.superclass访问父类属性,
      // 如果不想造成过多引用,也可把这句注释掉,因为多数时候是没必要的.
      absObj.superclass = sprPropty;
      //
      clazz.constructor = constructor;
  }
  
  return clazz;
}

 

OK, 大功告成,写个类承继例子测试一下.

 

//
//创建一个动物类
//
var Animal = CC.create(null, {

	//属性
	footprint  : '- - - - - - =',
		
	//类初始化方法,必须的,当用 new 生成一个类时该方法自动被调用,参见上定义.
	initialize : function(options){
		extend(this, options);
		alert('Animal initialize method is called.');
	},
	
	eat : function(){
		alert('Animal eat method is called.');
	},
	
	move : function(){
		alert('I am moving like this '+  this.footprint +' .');
	}
});

//
//创建一个Duke类
//
var Duke = CC.create(Animal, function(superclass){
	
	//在这可以定义一些类全局静态数据,该类每个实例都共享这些数据.
	//计算实例个类,包括派生类实例.
	var static_instance_counter = 0;
	
	function classUtilityFuncHere(){  }
	
	//返回类具体属性.
	return {
		//重写初始化方法
		//@override
		initialize : function(options) {
			alert('Initializing Duke class..');
			
			//调用父类初始化,这种方法比一般其它库的要简洁点吧,可以不管父类是什么.
			superclass.initialize.call(this, options);
			
			//做一些子类喜欢做的事.
			alert('Duke initialize method is called.');
			
			//读取或修改类静态属性
			static_instance_counter++;
		},
		
		//重写move方法,增加Duke自己的移动方式.
		move : function(){
			this.footprint = this.footprint + 'zzzzzzzz';
			
			superclass.move.call(this);
		},
		
		
		//重写eat方法,注意,里面不调用父类方法,即父类eat被覆盖了.
		eat : function(){
			alert('Duke is eating..');
		},
		
		//新增一个say方法,显示当前已经初始化的Duke类实例数量.
		say : function(){
			alert('the number of Duke instances is '+static_instance_counter);
		}
	};
});


var DukeChild = CC.create(Duke, function(superclass){
	return {
		move : function(){
			this.footprint = this.footprint + '++++++++++++=';
			superclass.move.call(this);
		},
		
		say : function(){
			alert(this.msg || '');
		}
	};
});

 

看看效果如何

 

(function test() {
	var animal = new Animal();
	animal.eat();
	animal.move();
	
	var dukeA = new Duke();
	dukeA.eat();
	dukeA.move();
	dukeA.say();
	
	var dukeB = new Duke();
	dukeB.eat();
	dukeB.move();
	dukeB.say();
	
	var dukeC = new DukeChild({msg : 'I am a child of duke.'});
	dukeC.move();
	dukeC.say();
})();
 

 

这是个人的一点经验之谈,望能抛砖引玉.

 

分享到:
评论

相关推荐

    JavaScript实现继承的几种方式

    继承是面向对象的核心特性之一,它允许一个对象(子类)从另一个对象(父类)获取属性和方法,从而形成类之间的层次结构。本篇文章将深入探讨JavaScript中实现继承的几种常见方式。 1. 原型链继承 JavaScript的原型...

    JavaScript学习之三 — JavaScript实现继承的7种方式

    继承是面向对象的核心特性之一,它允许一个对象(子类)获取另一个对象(父类)的属性和方法。本篇文章将深入探讨JavaScript实现继承的七种常见方式,帮助你更好地理解和运用这一概念。 1. 原型链继承(Prototype ...

    Javascript类的继承,使用this.callParent调用超类方法

    `this.callParent`方法(虽然不是原生JavaScript特性)提供了一种优雅的方式,允许我们在子类中调用父类的方法,从而保持代码的整洁和可维护性。理解并掌握这些概念对于进行高效的JavaScript开发至关重要。

    JavaScript继承的特性与实践应用深入详解

    `method`方法用于向构造函数的原型添加方法,而`inherits`方法则用于让一个构造函数继承另一个构造函数的原型。这样,我们可以通过链式调用来优雅地实现继承。 在实际应用中,JavaScript的继承机制不仅适用于简单的...

    浅析JavaScript实现基于原型对象的“继承”.pdf

    在基于类的语言中,对象是类的实例,并且一个类可以从另一个类继承。基于类的继承有两个主要优点: 1. 提高代码重用性高。如果我们新创建的类与已有的类有绝大部分相类似,则没有必要再重新定义这个完整的类。这样...

    浅谈Javascript实现继承的方法

    在Javascript中实现继承是面向对象编程的一个核心概念,它允许一个对象能够继承另一个对象的属性和方法。Javascript是一种基于原型的语言,这与基于类的语言如Java和C++有所不同,因此它的继承机制也显得特别独特。...

    【JavaScript源代码】JavaScript继承的三种方法实例.docx

    继承是面向对象编程的一个基本特征,它允许一个类(子类)继承另一个类(父类)的属性和方法,以此实现代码复用和结构化设计。 本文将深入探讨JavaScript中的三种主要继承方式,并通过具体的示例来帮助理解这些概念...

    javascript控件开发之继承关系

    JavaScript是一种广泛应用于网页和网络应用的脚本语言,尤其在前端开发中占据核心地位。控件开发是JavaScript应用中的重要部分,它涉及到UI组件的创建和功能实现。在这个主题中,“javascript控件开发之继承关系”...

    JavaScript继承机制研究.pdf

    原型链是JavaScript继承机制的核心,它允许一个对象从另一个对象中继承属性和方法。通过原型链,JavaScript可以实现多重继承,这使得JavaScript的继承机制更加灵活和强大。 构造函数方式继承 构造函数方式继承是一...

    java script 继承的实现

    JavaScript 是一种广泛应用于 Web 开发的脚本语言,它的继承机制是其面向对象特性的重要组成部分。在 JavaScript 中,继承主要用于创建类之间的关系,允许子类(派生类)继承父类(基类)的属性和方法,从而实现代码...

    在JavaScript中实现类的方式探讨

    在JavaScript中实现类的方式主要有几种,包括对象字面量...综上所述,JavaScript中实现类的方式多种多样,开发者可以根据实际需求和项目特性选择合适的方法。在实践中,往往需要结合使用这些方式,以达到最佳效果。

    javascript的prototype继承

    JavaScript的原型继承是其面向对象编程的一大特性,它基于原型链机制实现,允许一个对象可以从另一个对象继承属性和方法。这种继承方式不同于类继承,而是通过将子类的原型对象设置为父类的一个实例来实现。 在...

    js javascript zInherit 对象 继承

    总的来说,`zInherit`是JavaScript对象继承的一种实现,它利用原型链实现继承关系,使得子类可以继承和扩展父类的属性和方法。理解并熟练掌握这种继承方式,对于深入理解JavaScript的OOP特性以及编写高效的代码至关...

    javascript 继承派生

    **继承**是面向对象编程的关键概念,允许一个对象(子类)继承另一个对象(父类)的属性和方法。在JavaScript中,由于它没有内置的类结构,而是采用原型(prototype)链来实现继承。当一个对象作为另一个对象的原型...

    javascript 继承实现方法

    JavaScript是一门拥有动态类型、基于原型的语言,其继承不像一些静态类型语言(如Java或C++)那样有明确的类继承模型。在JavaScript中,继承通常是通过原型链(prototype chain)或者构造函数和原型来模拟实现的。...

    JavaScript是如何实现继承的(六种方式)_.docx

    在面向对象编程语言中,继承是一种非常重要的机制,它允许我们定义一个类去继承另一个类的特性(属性和方法)。这种特性使得代码复用变得可能,提高了软件开发的效率。在JavaScript中,由于其动态性质,继承的实现...

    详解JavaScript中基于原型prototype的继承特性_.docx

    在JavaScript中,对象可以直接从另一个对象继承属性和方法,这主要是通过原型链(prototype chain)来实现的。 首先,每个函数都有一个`prototype`属性,这个属性是一个对象,当通过该函数创建新对象时,新对象会...

    JavaScript继承机制探讨及其应用.pdf

    2. 构造函数继承(Constructor Inheritance):这是 JavaScript中另一种常用的继承机制,通过将一个构造函数的 prototype 属性设置为另一个构造函数的实例,从而实现继承。 3. 混合继承(Mixins Inheritance):这是...

    JavaScript原型式继承实现方法

    JavaScript中的原型式继承是一种实现对象继承的方式,它利用了JavaScript对象原型(prototype)的特性来实现对象间的属性和方法共享。这种方法由道格拉斯·克罗克福德在2006年的文章中提出,旨在避免自定义类型的...

    javascript面向对象特性代码实例

    第一种方法利用构造函数和apply、call方法来实现继承,这种方法的优点是可以实现多继承,但缺点是使用instanceof运算符的结果为false。第二种方法则是通过原型链来实现继承,这种方法的优点是代码结构清晰,但缺点是...

Global site tag (gtag.js) - Google Analytics