function Animal(){ this.species = "动物"; } function Cat(name,color){ this.name = name; this.color = color; } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; var cat1 = new Cat("大毛","黄色"); alert(cat1.species); // 动物
使用prototype完成继承,
1,Cat和Animal的属性都是构造函数定义的为什么可以通过prototype去设定,两个对象的prototype应该都是空的啊?
2,为什么 Cat.prototype = new Animal();之后prototype会包含三个属性(name,color,species)呢?我想的是把cat的prototype赋给了animal,应该只有animal的属性了?
问题1:
并不是空的, prototype是一个对象,他也有自己的原型链
问题2:
当Cat.prototype = new Animal()执行后,cat1继承的就是animal对象了,cat1本身有color和name属性,cat1的原型有animal属性,并不是,并不是题主所说的三个属性在一个对象中。因此当访问cat1的属性时,如果这个属性在cat1中,就直接得到,不在的话,从原型链对象中获取,直到找到这个属性为止(),或者直到顶层也没有找到,就返回undefined;
-----------------附上我前几天自己总结的,一起学习,
基于
__proto__
属性的原型链继承javascript每个对象都有原型,是通过一个叫做
__proto__
属性来连接起来的,这个属性是每个对象都有的(包括函数),最顶层的为Object.prototype
(更严谨地说,应该是图中的null,不过,这不是重点),从整体上来看,倒像是一棵以Object.prototype
对象为根的"原型链树"。大致长这样:(不要觉得javascript的原型链很深很复杂,其实事实上,一般原型链也就几层子,因为层数多了,效率就低,同时也难以维护(因为过于复杂),所以对于这棵树,更多的是拓展宽度,而不是高度)
现在我们知道,所有普通的原型链一般最终会指向内置的
Object.prototype
,显然,这个Object.prototype
对象不就可以内置一些比较通用的功能吗,这样如:.toString()
.valueOf()
.hasOwnProperty(...)
.isPrototypeOf(...)
prototype
属性与原型链的关系至此,更常见到的
protoType
属性没有提到,这个属性和原型链有什么关系呢。先举个例子吧,富士康(类)生产苹果手机(实例化对象),富士康就要对它生产出来的手机负责,那么就有一个质量规范来针对于产品,同理,通过函数的构造调用来实例化一个或多个对象,那么这些新对象的原型链是不是应该由这个函数工厂来负责呢,既然如此,直觉的看,有两种方法可以让这些新对象加入到“原型链森林”的家族中。
函数也是对象啊,那也有原型链,这简单,你原型链着谁我也链着谁,反正我是你生产出来的,不行的话,我链你也行啊。
给函数一个属性,指向一个对象,用来规定通过该函数构造出来的新对象统统指向这个对象。(事实上,函数的prototype属性干的就是这个,同时,也意味着只有函数才有prototype属性)。
先来说说,为什么方法1不可以,首先,我们不是为了原型链而原型链,算了,还是直接看代码吧:(切换一下风格)
( 切换回来 )
就这样,所有通过函数构造出来的对象(即通过new),统统指向函数的prototype属性指向的对象。
恬不知耻的推荐一下自己的文章:
http://zjy.name/archives/javascript-object-oriented-1.html
http://zjy.name/archives/javascript-object-oriented-2.html