最近在研究javascript原型链继承这一块碰到一个细节问题,引起了我的好奇,但是一直想不明白是为什么,请求大神解答:functionShape(){this.name='shape';this.toString=function(){returnthis.name;}}functionTwoDShape(){this.name='2dshape'}functionTriangle(side,height){this.name='triangle';this.side=side;this.height=height;this.getArea=function(){returnthis.side*this.height/2;}}Triangle.prototype=newTwoDShape();TwoDShape.prototype=newShape();Triangle.prototype.constructor=Triangle;TwoDShape.prototype.constructor=TwoDShape;如上段代码所示,我建立了一个继承链,从Shape到TwoDShape,再由TwoDShape到Triangle,当我再执行以下代码时:varshape1=newTriangle(10,9);console.log(TwoDShape.prototype.isPrototypeOf(shape1));//输出false程序输出false,我的理解,是isPrototypeOf寻找的是shape1最直接的那个原型,即Triangle.prototype,而这里TwoDShape.prototype不是其直接原型,所以输出了false;然鹅,我在《javascript面向对象编程指南》这本书上看到的实践则恰恰相反:书上在实现继承时是这样做的:functionShape(){}Shape.prototype.name='shape';Shape.prototype.toString=function(){returnthis.name;}functionTwoDShape(){};TwoDShape.prototype=newShape();TwoDShape.prototype.constructor=TwoDShape;TwoDShape.prototype.name='2dshape';functionTriangle(side,height){this.side=side;this.height=height;}Triangle.prototype=newTwoDShape();Triangle.prototype.constructor=Triangle;Triangle.prototype.name='triangle';Triangle.prototype.getArea=function(){returnthis.side*this.height/2;}在执行了这段代码后再console.log(TwoDShape.prototype.isPrototypeOf(shape1));此时则会输出true,我不明白的,是这两种继承方式,不都是通过原型链继承吗?为什么两者在这个点上的输出会不一样呢?我还有个问题,就是在学习javascript时常常碰到这样理解起来很匪夷所思的问题,应该怎样更好的理解这门语言呢?
2 回答
幕布斯6054654
TA贡献1876条经验 获得超7个赞
一楼已经说得够多了,我就简介一点。你唯一的区别就是Triangle.prototype=newTwoDShape();TwoDShape.prototype=newShape();这两句没有错误,但其中包含重写原型链的问题,在TwoDShape.prototype=newShape()这句之前,TwoDShape.prototype的原型对象是Object,而Triangle也是这时继承的TwoDShape。而TwoDShape.prototype=newShape(),这句话之后,TwoDShape经历了一次重写原型链的过程,此时其原型对象由Object变为了shape;但这并不会改变Triangle的原型指向,其仍指向老的TwoDShape原型构造出来的对象;所以,所以TwoDShape.prototype.isPrototypeOf(shape1)打印false没有问题,因为shape1的构造函数Triangle的原型TwoDShape已经不再是哪个单纯的Object了,已不再单纯。大清早说这么绕的话,也是累
添加回答
举报
0/150
提交
取消