javascript - 关于js对象继承的问题?
PHPz
PHPz 2017-04-11 09:51:44
0
2
163
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的属性了?

PHPz
PHPz

学习是最好的投资!

reply all (2)
Ty80

问题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的原型链很深很复杂,其实事实上,一般原型链也就几层子,因为层数多了,效率就低,同时也难以维护(因为过于复杂),所以对于这棵树,更多的是拓展宽度,而不是高度)

note: 更准确的说,应该称之为"原型链森林",因为我们可以更改一个对象的__proto__属性值(尽管ES5中不建议这么做),不一定最终指向Object.prototype

  • 现在我们知道,所有普通的原型链一般最终会指向内置的Object.prototype,显然,这个Object.prototype对象不就可以内置一些比较通用的功能吗,这样如:

    • .toString()

    • .valueOf()

    • .hasOwnProperty(...)

    • .isPrototypeOf(...)

prototype属性与原型链的关系

至此,更常见到的protoType属性没有提到,这个属性和原型链有什么关系呢。

先举个例子吧,富士康(类)生产苹果手机(实例化对象),富士康就要对它生产出来的手机负责,那么就有一个质量规范来针对于产品,同理,通过函数的构造调用来实例化一个或多个对象,那么这些新对象的原型链是不是应该由这个函数工厂来负责呢,既然如此,直觉的看,有两种方法可以让这些新对象加入到“原型链森林”的家族中。

  1. 函数也是对象啊,那也有原型链,这简单,你原型链着谁我也链着谁,反正我是你生产出来的,不行的话,我链你也行啊。

  2. 给函数一个属性,指向一个对象,用来规定通过该函数构造出来的新对象统统指向这个对象。(事实上,函数的prototype属性干的就是这个,同时,也意味着只有函数才有prototype属性)。

先来说说,为什么方法1不可以,首先,我们不是为了原型链而原型链,算了,还是直接看代码吧:(切换一下风格)

// IPone: 我要加入原型链家族,我不管,我不管 // FSK: 我虽然生产了你,但我有自己的属性 FSK.name = "fushikang"; // 名字--富士康 FSK.coordinate = "中国";// 坐标--中国 FSK.productName = "IPone"; // 产品--IPone ... // FSK: 你看,很明显,我的属性与你的属性之间没有任何关系,你链着我没有任何用处, // 我给你指条明路,我有一个属性,叫做prototype, 你们都跟着它吧,这也是上头的意思。 // 哦,对了,如果某一天你忘了我,在你的上一层原型链上又一个constructor属性, // 通过它,你可以找到我。

( 切换回来 )
就这样,所有通过函数构造出来的对象(即通过new),统统指向函数的prototype属性指向的对象。

function myFun(){ ... } var a = new myFun(); console.log( a.__proto__ === myFun.prototype ); // true console.log( myFun ==== a.__proto__.constructor ); // true;
    大家讲道理

    恬不知耻的推荐一下自己的文章:
    http://zjy.name/archives/javascript-object-oriented-1.html
    http://zjy.name/archives/javascript-object-oriented-2.html

      Latest Downloads
      More>
      Web Effects
      Website Source Code
      Website Materials
      Front End Template
      About us Disclaimer Sitemap
      php.cn:Public welfare online PHP training,Help PHP learners grow quickly!