js的继承
2014-03-13 15:05
330 查看
原文链接:http://www.wmhfly.com/web-skill/js-extends.html
最近断断续续地看《javascript设计模式》 ,对它里面介绍“继承”一章做一个总结。js的继承,和其他面向对象的编程语言不同,它没有实现可以用“extends”关键字方式继承,而是要通过一些技巧来实现。继承:就是一个对象直接使用另一对象的属性和方法 ;使用继承可以让代码变的简洁,耦合度低,可以高度重用代码。
2、原型式继承
3、掺元类
1.1、类式继承使用的是“new,this,prototype”等关键字,用构造函数的方式实现。只要new一个实例,就可以继承构造函数定义的属性和方法。一般约束:构造函数命名大写开头,属性用this添加,方法添加到prototype对象中。下面是一个简单的例子:
1.2、原型链:可以让一个类继承另一个类。下面是一个简单的例子:
二、原型式继承:
原型式继承是利用clone克隆函数实现,这里不再采用构造函数的方式,而是要忘记它。原型是创建一个对象,用字面量方式创建,以它做为模型,克隆副本。需要注意的是,如果给克隆出的对象加属性,则是新增一个属性,如果是给引用类型的值操作,则会影响全部克隆对象。这就是它对继承而来的成员读和写的不对等性。下面是简单的例子:
三、掺元类:
掺元类就是把一些通用的方法封装起来,然后在想要用到它们的地方,用augment函数复制过来。如果想避免全部复制,也可以指定你要复制的方法。看下面的例子:
最近断断续续地看《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_url1.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();