web development blog

> 前端技术 js继承话题

最近断断续续地看《javascript设计模式》 ,对它里面介绍“继承”一章做一个总结。js的继承,和其他面向对象的编程语言不同,它没有实现可以用“extends”关键字方式继承,而是要通过一些技巧来实现。继承:就是一个对象直接使用另一对象的属性和方法 ;使用继承可以让代码变的简洁,耦合度低,可以高度重用代码。

js的继承方式有:

  • 1、类式继承(原型链/extend函数)
  • 2、原型式继承
  • 3、掺元类

一、类式继承:

1.1、类式继承使用的是“new,this,prototype”等关键字,用构造函数的方式实现。只要new一个实例,就可以继承构造函数定义的属性和方法。一般约束:构造函数命名大写开头,属性用this添加,方法添加到prototype对象中。下面是一个简单的例子:

/**
 * 构造函数
 * SiteInfo
 */
function SiteInfo(url){
	this.base_url = url;
}
SiteInfo.prototype.get_url = function(){
	return this.base_url;
}

//创建一个实例,自动继承类的属性和方法
var site = new SiteInfo('http://www.wmhfly.com');

site.get_url();//获取base_url

1.2、原型链:可以让一个类继承另一个类。下面是一个简单的例子:

/**
 * 构造函数
 * IframeInfo
 */
function IframeInfo(url,path){
	SiteInfo.call(this,url);
	this.path = path;
}
IframeInfo.prototype = new SiteInfo();
IframeInfo.prototype.constructor = IframeInfo;
IframeInfo.prototype.get_iframe_url = function(){
  //调用超类的方法
	return this.get_url()+this.path;
}

//创建一个实例,自动继承子类和超类的属性和方法
var iframe = new IframeInfo('http://iframe.wmhfly.com','/iframe.html');

iframe.get_iframe_url();//获取get_iframe_url

1.3、extend函数:2个版本,版本二解决了版本一超类名固化在子类构造函数中的问题。

/**
 * extend
 * 版本一
 */
function extend(subClass,superClass){
	var F = function(){};
		F.prototype = superClass.prototype;
		subClass.prototype = new F();
		subClass.prototype.constructor = subClass;
}

/**
 * 构造函数
 * TagInfo
 */
function TagInfo(url,tag){
	SiteInfo.call(this,url);
	this.tag = tag;
}

extend(TagInfo,SiteInfo);

TagInfo.prototype.taglist = function(){
	var temlist = '';
	for(var i=0,len=this.tag.length;i'+this.tag[i]+'';
	}
	return temlist;
}

//创建一个实例,自动继承子类和超类的属性和方法
var tag = new TagInfo('http://wmhfly.com/tag',['html','css',''js]);
tag.taglist();//获取标签字符串

/**
 * extend
 * 版本二
 */
function extend(subClass,superClass){
	var F = function(){};
		F.prototype = superClass.prototype;
		subClass.prototype = new F();
		subClass.prototype.constructor = subClass

	subClass.superClass = superClass.prototype;
	if(superClass.prototype.constructor==Object.protoype.constructor){
		superClass.prototype.constructor = superClass
	}
}
/**
 * 构造函数
 * LinkInfo
*/
function LinkInfo(url,linkArr){
   //解决超类固化
	LinkInfo.superClass.constructor.call(this,url);
	this.linkArr = linkArr;
}

extend(LinkInfo,SiteInfo);
LinkInfo.prototype.linklist = function(){
	var temlist = '';
	for(var i=0,len=this.linkArr.length;i'+this.linkArr[i]+'';
	}
	return temlist;
}
var olink = new LinkInfo('http://wmhfly.com/',['opencart','zencart']);
olink.linklist()//获取标签字符串

二、原型式继承:

原型式继承是利用clone克隆函数实现,这里不再采用构造函数的方式,而是要忘记它。原型是创建一个对象,用字面量方式创建,以它做为模型,克隆副本。需要注意的是,如果给克隆出的对象加属性,则是新增一个属性,如果是给引用类型的值操作,则会影响全部克隆对象。这就是它对继承而来的成员读和写的不对等性。下面是简单的例子:

/**
 * 克隆函数
 */
function clone(object){
	function F(){};
	F.prototype = object;
	return new F();
}

/**
 *原型式继承
 */
var BaseInfo = {
	version:'1.0',
	skill:['html','css','js'],
	get_version:function(){
		return this.version;
	}
}

var _base01 = clone(BaseInfo);
var _base02 = clone(BaseInfo);
_base01.skill.push('php');//影响全部克隆对象
_base02.version = '2';//新增一个属性

三、掺元类:

掺元类就是把一些通用的方法封装起来,然后在想要用到它们的地方,用augment函数复制过来。如果想避免全部复制,也可以指定你要复制的方法。看下面的例子:

/**
 * 掺元类
 * augment
 */
function augment(receivingClass, givingClass) {
  if(arguments[2]) { // Only give certain methods.
    for(var i = 2, len = arguments.length; i < len; i++) {
      receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
    }
  } 
  else { // Give all methods.
    for(methodName in givingClass.prototype) { 
      if(!receivingClass.prototype[methodName]) {
        receivingClass.prototype[methodName] = givingClass.prototype[methodName];
      }
    }
  }
}

/*
 * Method Tool
 */
var MTool = function(){};
MTool.prototype = {
	gYear:function(){
		return (new Date()).getFullYear();
	},
	gMonth:function(){
		return (new Date()).getMonth()+1;
	}
}

function TimeInfo(){}

augment(TimeInfo,MTool,'gYear');
var _timeInfo = new TimeInfo();
_timeInfo.gYear();

总结:

这三种方法各有优缺点,类式继承比较普遍,因为大家都比较熟悉这种构造函数方式,但是内存占用比较大。而原型式继承,占用内存比较小,但是包含数组,或者对象类型的克隆比较麻烦。掺元类是共享方法,不需要继承,只是想要用到的地方,就复制进来。

 

-留言评论-

  • 留言载入中...

-拍砖-

 

首页|前端技术|编程/php|生活|关于我

Copyright © 2012 wmhfly.com