JS 原型继承原型链图解

  • Post author:
  • Post category:其他


/**
 * 继承
 * SuperType是被继承的对象的构造函数
 * SubType是继承的对象的构造函数
 */
function SuperType(name) {
  this.name = name;
  this.color = ['red', 'blue'];
}
SuperType.prototype.sayName = function() {
  console.log(this.name);
}
function SubType(name, age) {
  SuperType.call(this, name);
  this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function() {
  console.log(this.age);
}
// inheritPrototype是实现继承的核心
function inheritPrototype(subType, superType) {
  subType.prototype = Object.create(superType.prototype);
  subType.prototype.constructor = subType;
}
let father = new SuperType('papa');
let son = new SubType('son', 18);
father.sayName();// papa
son.sayName();// son
son.sayAge();// 18

在原型链上我们主要关注两种类型:对象和函数

函数:有三个重要的法宝分别是

1.__proto__

2.prototype

3.constructor

而对象是函数小弟,只有两个法宝:

(此对象不是指原型链顶端Object,就是普通对象)

1.__proto__

2.constructor

注意点:

一个函数的原型对象的constructor应该指向该函数

对于

constructor这个属性,它只有prototype对象才有

。每个函数在new一个对象的时,JS会同时创建一个该函数对应的

prototype

对象,而

函数new的对象.__proto__ === 该函数.prototype,该函数.prototype.constructor===该函数本身

,故函数

new

的对象即使自己没有

constructor

属性,它也能通过

__proto__

在函数原型对象上找到对应的

constructor

属性,所以任何对象最终都可以通过

construtor

(或是继承的)找到其构造函数

那这有什么意义吗?有,并且这里有个很大的坑,跟后面的继承有关。上代码

function Person() {};
function Student() {};
var p = new Person(); // Student.prototype = Object.create(Person.prototype)
Student.prototype=p; //继承原型
var s=new Student();

显而易见,Student继承自Person,因为我们将Student.prototype 指向了Person的实例对象p。(或者用更好的方法Student.prototype=Object.create(Person.prototype));那你思考一下下面输出什么

Student.prototype.__proto__ // Person.prototype
Student.prototype.constructor // Person
s.__proto__ // Student.prototype
s.constructor // Person

输出是不是不符合预期:

  • Student.prototype.constructor不指向自身Student,竟然指向Person。找个后爸?原因是代码写了Student.prototype=p。所以之后要纠正回来Student.prototype.constructor=Student,这暂时不是我们考虑的重点。

    重点要知道为什么说实例对象的constructor不是自身的
  • 来了来了~~  s.constructor 指向竟然又不是

    new

    它的

    Student

    ,它也奇怪的指向了

    Person

    。这里就证明了其实 s (这个 new 出来的实例对象)本身是不具有

    constructor

    属性的,它是通过 __proto__ 找到 Student.prototype,然后再找到Person的。


Tip:

1.为了方便看图,函数最多指出三条线,对象最多指出两条线

2.一个对象(函数)自身没找到的方法或属性,会沿着–proto–的指向再去寻找

3.先有Object.prototype(原型链顶端),Function.prototype继承Object.prototype而产生,最后,Function和Object和其它构造函数继承Function.prototype而产生

4. 所有的构造器都继承于Function.prototype

5.天知道Object.prototype的Object到底指代什么

6.Function.proto===Function.prototype成立。既是也不是。

是:从原型链上看,Function对象的prototype是在Function构造函数的原型链上的,实例的说法成立。

不是:Function是内建对象,如果说Function对象是Function构造函数创建,那Function构造函数又是谁创建的呢?

详细内容:

https://www.processon.com/diagraming/5d5ba626e4b08b95b824f05a

参考资料:

https://github.com/jawil/blog/issues/13


https://juejin.im/post/5caefd575188251b2822c17e



版权声明:本文为weixin_41976150原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。