您的位置:首页 > Web前端 > JavaScript

js的继承

2014-03-13 15:05 330 查看
原文链接:http://www.wmhfly.com/web-skill/js-extends.html

最近断断续续地看《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<len;i++){ a="" href=""'" n="+this.tag[i]+" temlist="">'+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<len;i++){ a="" href="' temlist +this.get_url()+??link=">'+this.linkArr[i]+'';
}
return temlist;
}
var olink = new LinkInfo('http://wmhfly.com/',['opencart','zencart']);
olink.linklist()//获取标签字符串</len;i++){></len;i++){>


二、原型式继承:

原型式继承是利用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();

总结:

这三种方法各有优缺点,类式继承比较普遍,因为大家都比较熟悉这种构造函数方式,但是内存占用比较大。而原型式继承,占用内存比较小,但是包含数组,或者对象类型的克隆比较麻烦。掺元类是共享方法,不需要继承,只是想要用到的地方,就复制进来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: