原型链和继承

在一切开始之前回顾一下类、实例、prototype、proto的关系

function Person(nick, age){
    this.nick = nick;
    this.age = age;
}
Person.prototype.sayName = function(){
    console.log(this.nick);
}
var p1 = new Person();
p1.sayName();
  • 我们通过函数定义了类Person,类(函数)自动获得属性prototype
  • 每个类的实例都会有一个内部属性proto,指向类的prototype属性

有趣的现象

我们定义一个数组,调用其valueOf方法

[1, 2, 3].valueOf(); // [1, 2, 3]

很奇怪的是我们在数组的类型Array中并不能找到valueOf的定义,根据之前的理论那么极有可能定义在了Array的prototype中用于实例共享方法,查看一下


我们发现Array的prototype里面并未包含valueOf等定义,那么valueOf是哪里来的呢?

一个有趣的现象是我们在Object实例的proto属性(也就是Object的prototype属性)中找到了找到了这个方法

那么Array的实例为什么同样可以查找到Object的prototype里面定义的方法呢?

查找valueOf过程

因为任何类的prototype属性本质上都是个类Object的实例,所以prototype也和其它实例一样也有个proto内部属性,指向其类型Object的prototype

我们大概可以知道为什么了,自己的类的prototype找不到的话,还会找prototype的类型的prototype属性,这样层层向上查找

大概过程是这样的

1.记当前对象为obj,查找obj属性、方法,找到后返回
2.没有找到,通过obj的proto属性,找到其类型Array的prototype属性(记为prop)继续查找,找到后返回
3.没有找到,把prop记为obj做递归重复步骤一,通过类似方法找到prop的类型Object的 prototype进行查找,找到返回


这就是传说中的原型链,层层向上查找,最后还没有就返回undefined

类型

我们之前介绍过instanceof操作符,判断一个对象是不是某个类型的实例

[1, 2, 3] instanceof Array; //true

可以看到[1, 2, 3]是类型Array的实例

[1, 2, 3] instanceof Object; //true

这个结果有些匪夷所思,怎么又是Array的实例,又是Object的实例,这不是乱套了

其实这个现象在日常生活中很常见其实,比如我们有两种类型

  • 类人猿
  • 动物

我们发现黑猩猩既是类人猿这个类的物种(实例),也是动物的实例

是不是悟出其中的门道了,类人猿是动物的一种,也就是说我们的两个类型之间有一种父子关系

这就是传说中的继承,JavaScript正是通过原型链实现继承机制的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容