JS 原型继承原型链图解

/**
 * 继承
 * 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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值