手机版

浅析Javascript原型继承推荐第1/2页

时间:2021-11-25 来源:互联网 编辑:宝哥软件园 浏览:

JS不提供所谓的类继承,据说是在2.0中加入的,但是所有浏览器要实现2.0的特性,肯定需要N年的时间。昨天看了crockford的一个视频,讲解JS的继承。根据PPT,它被分为三类:原型,假经典和寄生遗传。下面主要介绍原型继承:创建函数对象时,给它一个原型成员,它是一个包含构造函数成员的对象,构造函数成员是对函数对象的引用。

这里,我们首先区分原型属性和构造器属性。也就是说,需要区分构造函数、函数和对象实例。其实在JS中,构造函数就是函数,函数就是构造函数,对象实例就是通过var obj=new函数();此表单的新创建实例。这些区别是关于原型和构造器的。从上面的英文可以看出,prototype是一个定义了构造函数的对象,所以我们可以推断构造函数是一个对象实例的属性!而不是函数(构造函数)的属性。相反,原型是函数(构造函数)的属性,而不是实例!复制的代码如下://在下面的代码示例中,MyObj是函数(构造函数),Obj是实例函数MyObj(id){ this . id=id;} var obj=new MyObj(1);Alert(MyObj.constructor) //本地代码alert (obj。构造函数)//MyObj。tostring () alert (myobj。原型)//[对象对象]警报(obj。prototype)//undefined我们可以看到myobj没有JS意义上的构造函数属性。alert(MyObj.constructor)的代码中有一些东西:“

这是因为MyObj是一个function,所以它的构造函数是一个局部Function对象,也就是说MyObj是由Function构造的。但这对我们来说意义不大,因为它已经不在JS层面上了。因此,可以认为MyObj不具有JS意义上的constrcutor属性。Alert(obj.prototype)从这一行,我们可以看到obj实例没有prototype属性。好了,现在区别清楚了,我们可以看到原型继承了。如果不把这个区分清楚,恐怕下面会很晕。复制代码如下: function gizmo(id){ this . id=id;} gizmo . prototype . ToString=function(){ return ' gizmo ' this . id;};函数Hoozit(id){ this . id=id;} hoozit . prototype=new Gizmo();hoozit . prototype . test=function(id){ return this . id===id;};注意这一行: hoozit . prototype=new Gizmo();这一行是原型继承的核心代码。还需要注意的是,只有在新增Gizmo()之后,才能添加test等其他方法,这个顺序不能颠倒!如果先添加test等方法,然后在new Gizmo()中添加,那么原来添加的所有方法都将丢失。具体原因在下面分析后就清楚了。复制的代码如下: hoozit . prototype . test=function(id){ return this . id===id;};hoozit . prototype=new Gizmo(2);var h=new Hoozit();alert(h . test(3));//这里会有错误!

仔细看看上图。这是原型继承的示意图。左下角的新Hoozit(搅拌)代表新创建的对象。为了方便下面的陈述,我们称他为objH1。最右边的灰色箭头是原型继承链。根据文章开头的英文,我们知道每个函数都有一个原型,就是一个对象,这个对象包含一个构造函数属性。其中,Object、Gizmo和Hoozit是函数。可以看到其中有一个原型项,这个原型指向一个对象,这个对象有一个构造函数属性,构造函数指向自身。复制的代码如下: alert(gizmo . prototype . constructor o==gizmo)//true。然而,这里发生了意外。我们发现Hoozit原型对象中没有构造函数属性,但是这个函数右侧有一个空对象,里面包含了构造函数属性?为什么呢?这个问题会在原型继承的过程中出现。主要是因为hoozit . prototype=new Gizmo();这句话引起的。这句话的意思是创建一个新的Gizmo对象,并将其分配给Hoozit的原型!那么,仔细想想,Hoozit最初的原型对象是断开的吗?是的,就是这样。所以不能再访问带有构造函数属性的空对象了!现在还有一个问题,通过hoozit . prototype=new Gizmo();在这一行代码之后,Hoozit.prototype.constructor指向哪里?很简单。你知道在哪里吗(新Gizmo())。构造函数点?从上图可以清楚的看到,它指的是Gizmo功能。因此,我们得出结论,当前的Hoozit.prototype.constructor也指向那里!复制代码如下: alert(hoozit . prototype . constructor===gizmo);//真以上一行代码验证了我们的猜测!好了,我们已经完成了函数(构造函数端),接下来我们将讨论实例对象端:每个实例对象都有一个构造函数属性,并指向构造函数(函数)。而每一个新的实例都是一个原型构造函数的实例:复制代码如下: varobjg1=new gizmo()alert(gizmo . prototype . constructor的obj G1实例)//true alert(gizmo . prototype . constructor==obj G1 . constructor);//true为什么不以objH1为例,因为他的构造函数不是他自己的,而是Gizmo对象的。然后我们来验证一下:复制的代码如下: alert(objh1 . constructor==obj G1 . constructor)//true alert(gizmo . prototype . constructor的obj h1实例)//true。看到了吗?其实这个问题不大。如果不使用instanceof检查父对象或使用构造函数进行原型回溯,这个问题就无法解决。如果你想解决这个问题呢?在Prototype框架的Class.create方法中,给出了一个方法,具体请参考:http://blog . csdn . net/kitty Jie/archive/2009/07/13/4345568 . aspx,这里我简单说两个方法:12阅读下页全文。

版权声明:浅析Javascript原型继承推荐第1/2页是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。