JS面向对象从创建对象到对象继承_第1页
JS面向对象从创建对象到对象继承_第2页
JS面向对象从创建对象到对象继承_第3页
JS面向对象从创建对象到对象继承_第4页
JS面向对象从创建对象到对象继承_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1/1JS面向对象,从创建对象到对象继承以前写过一篇关于JS创建对象的帖子,JS创建对象的几种方法,突然想温习一下,所以写了下面的小例子,用来回顾这七种createpattern。

每种pattern都有自己的特色。

1工厂模式中,在构造函数内部用o={}创建一个新对象,最后返回这个对象。

当实例化时,不需要用new关键字,就像调用一般的方法一样。

我们可以把create函数设想成一个贴牌工厂,面对不同的需求,制作出内在相同,标签不同的产品。

工厂模式最大的问题是容易和普通函数混淆,方便归方便,但我们只能通过命名来确认它是一个构造函数。

/*1.factorypattern*/functioncreatePerson(name,age,job){varo={};//newobjecto.name=name;o.age=age;o.job=job;o.friends=[ansel,suisa];o.sayName=function(){alert(factorypattern:+this.name);};returno;}vartanya=createPerson(tanya,28,SoftwareEngineer);tanya.sayName();/*tips:o={}insidethecreatefunctionnothisinthecreatefunction*/2构造函数模式中,用new关键字来实例化对象,在构造函数内部使用this,无需返回任何对象。

构造函数相比工厂函数更加OO啦,并且可以将它的实例标识作为一种特定的类型。

像String,Array一样的使用自定义的类型。

但是,它的问题是不断的拷贝拷贝,每new一次就造出一份副本,每个方法都要在每个实例上重新创建一遍,varperson1=newTanya();person1.sayName();/*tips:publicshareofalltheentitiesifnoreturn,thenneednew.elseyoumayusereturn.*/4构造函数模式和原型模式的混合类型。

特点就是想隐私,那么就用构造函数模式去copy封装在自己的包里,想要share的地方就用prototype。

/*4.hybridconstructorprototypePattern*/functionStudent(name,sno){this.name=name;this.sno=sno;this.sayName=function(){alert(hybridconstructorprototypePattern:+this.name);}}//Student.prototype.teacher=[ansel,tanya];//Student.prototype.sayTeacher=function(){alert(hybridconstructorprototypePattern:+this.teacher);};Student.prototype={constructor:Student,teacher:[ansel,tanya],sayTeacher:function(){alert(hybridconstructorprototypePattern:+this.teacher);}}varwang=newStudent(wang,12);varli=newStudent(li,13);wang.sayName();li.sayName();wang.sayTeacher();li.sayTeacher();/*tips:somethingyouneedtobepublicshare,andsomethingyouwanttobeprivate.weoftenusethismode,becauseanythingnevergoesinextrmelyway.*/5有些时候别人做过的事情我们不想再做,如果别人还没有做,那么我们就去做一遍,这种情况就是动态原型模式,无非就是if没这个函数...doprototype。

/*5.dynamicprototypepattern*/functionDogs(name){this.name=name;this.showName=function(){alert(this.name);}if(typeofthis.shout!=function){Dogs.prototype.shout=function(){alert(dynamicprototypepattern:wangwang);}}}varxixi=newDogs(xixi);varmimi=newDogs(mimi);xixi.showName();xixi.shout();mimi.showName();mimi.shout();/*tips:sometimes,functionisalreadydefined,ifitalreadydefined,youmaynotdefineagain,elseyoushouldmakeprototypeattributesfunctionsdynamically,.*/6寄生构造函数模式更像是工厂模式,几乎一模一样,不过在每次实例化对象的时候用了一个new。

这种模式的作用是在特殊情况下用来为对象创建构造函数。

但是就像它的名字非常的怪异一样,这不是一种被推崇的创建对象模式,因为不能依赖instanceof操作符来确定对象的类型,红皮书上的解释是:

构造函数返回的对象与在构造函数外部创建的对象没有什么不同。

那么我就姑且理解成这种模式对外看不到创建它的对象的类型,所有通过此模式创建的实例都像一个个找不到厂家的无牌商品,工厂模式也有这样的问题。

/*6.parasiticconstrctorpattern(hybirdfactory)*/functionPerson1(name,age,job){varo=newObject();o.name=name;o.age=age;o.job=job;o.sayName=function(){alert(this.name);};returno;}varfriend=newPerson1(Nicholas,29,SoftwareEngineer);friend.sayName();//Nicholas/*tips:similartofactorypattern,butusenewinentities*/7稳妥构造函数模式,这种模式的设计初衷是绝对保守的,他的目的是安全,手段是不用this,不用new,和工厂模式、寄生构造函数模式一样instanceof失效,保守的人永远成不了气候,所以这是一种方法,但不会是主流。

/*7.durableconstructorpattern*/functionPerson2(name,age,job){varo=newObject();o.name=name;o.age=age;o.job=job;o.sayName=function(){alert(name);};returno;}varfriend=Person2(Nicholas,29,SoftwareEngineer);friend.sayName();//Nicholas/*tips:Besurenothisandnewinyourcodeexcepto=newObject().*/红皮书下面的章节是关于对象继承的,个人觉得相比创建对象,对象继承显得更为重要,不过前者是基础。

很多OO都支持两种继承,分别是接口继承和实现继承,很遗憾ECMAScript无法实现接口继承,它的继承主要依靠原型链。

一原型链继承关于原型链,我以前写过一篇帖子js原型链原理看图说话。

在这篇帖子中介绍了每个实例中都默认拥有属性prototype,在很多浏览器中与其对应的属性叫__proto__。

学过链表的人很好理解,如果我要认某个人当爸爸,我只要把指针指向他,由于每个实例的链表中都只有一个prototype属性,所以通过原型链只能认一个爸爸。

按这个逻辑,通过原型链应该无法实现多重继承!写个例子验证一下。

!DOCTYPEhtmlhtmlheadtitleapply,call,bind/titlescripttype=text/javascript/*Ioftenconfusedwiththethreefunction,thisexamplegetadeepresearchofthem*/functionbaseType1(){this.name=tanya;}functionbaseType2(){this.age=28;}functionsubType(){}subType.prototype=newbaseType2();subType.prototype=newbaseType1();varinstance=newsubType();alert(instance.name);alert(instance.age);/script/headbody/body/html果然,后一个原型的赋值会覆盖前一个,也就是说通过原型链只能继承离实例化最近的一个原型对象。

原型链继承的本质就是一个单链表的深度搜索。

1搜索实例2搜索subTtotype3搜索baseTtotype一环一环,直到搜索在prototype属性等于null时,才会停下。

有几点需要记住的:

1所有的对象都继承自Object对象,就像所有的DOM对象都继承自window对象一样,Object对象提供了很多我们喜欢的方法。

2确定原型和实例的关系可以使用instanceof操作符和isPropertyOf()方法。

3在原型链上重写方法会屏蔽原来的方法。

4通过原型链条实现继承时,不能使用对象字面量创建原型方法。

因为对象字面量可以理解成一个实实在在的对象,对象可以成为原型但是会切断原型链。

5由于js中的引用类型实际上保存的是一个指针,所以在原型链上任意一个引用类型值的原型属性都会被所有实例共享。

下面的例子说明,如果是基本类型值不会被所有实例共享:

functionbaseType1(){this.name=tanya;}functionsubType(){}subType.prototype=newbaseType1();varinstance=newsubType();varinstance2=newsubType();instance2.name=ansel;alert(instance.name);//tanyaalert(instance2.name);//ansel但若替换成引用类型,就相当于所有实例共享引用的属性啦functionbaseType1(){this.name=[tanya,ansel];}functionbaseType2(){this.age=28;}functionsubType(){}subType.prototype=newbaseType1();varinstance=newsubType();varinstance2=newsubType();instance.name.push(xixi);alert(instance.name);//tanya,ansel.xixialert(instance2.name);//tanya,ansel,xixi因为原型链继承中引用类型有这种不分你我不分彼此的状态,所以constructorstealing技术被引入。

二借用构造函数继承(constructorstealing)constructorstealing技术的基本思想是:

在子类型构造函数的内部调用基类的构造函数,即在subType中调用baseType.call(this)来实现继承。

通过这种技术,可以在子类型的构造函数中向父类传递参数。

并且在子类型内部复制引用类型,保证引用类型的不共享。

其本质就是在subType中调用baseType.call(this)在subType内部clone了baseType的所有的属性和方法。

看看下面的例子:

functionbaseType(){this.name=[tanya,ansel];}functionsubType(){baseType.call(this);}subType.prototype=newbaseType();varinstance1=newsubType();varinstance2=newsubType();instance1.name.push(xixi);alert(instance1.name);//tanya,ansel.xixialert(instance2.name);//tanya,ansel但是这种技术的问题在于在超类型的原型中定义的方法对于子类型是不可见的,这就意味着所有的类型都只能使用构造函数模式。

三组合继承模式(原型链+借用构造函数)最常用的办法肯定是折衷的产物,于是结合了原型链的优势和constructorstealing的优势的组合继承模式应运而生。

组合继承模式有一个约定,那就是,用原型链实现对原型属性和方法的继承,而使用call或者apply来实现对实例属性的继承。

四原型式继承原型继承的本质是:

fuctionobject(o){functionF(){}F.prototype=o;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论