阅读 241

源解 0 - 你怎么理解原型链?

背景

js 是一个面向对象的动态脚本语言,而设计者当初10日创造javaScript,参考了当时面向对象语言程序设计,又考虑到是为Web做脚本动态化服务的,因此需要尽可能轻量,就舍弃了面向对象语言中的 Class 概念,但是核心设计理念,比如封装 继承 多态等需要保留,而针对继承,就设计了js原型链来实现js 继承。

设计原理

抽象出某些类共有的属性 行为,封装为一个类(父类),而当某个类(子类)需要实现这些属性,行为,就可以直接继承这个类(父类),这就是继承最大的功能.

那么原型链如何实现的上述功能?

首先js万物皆为对象,包括Function也是一个对象,所以要实现原型继承,还得从对象下手 !
那么设计者就在每个对象里都加入了一个属性 从最顶端的Object 到你实例化的一个var a = [] 数组对象都有这个属性 _ proto _.
有什么用呢?

这个_proto_属性存储着一个引用,指向它的构造函数的原型对象 (prtotype)。

原型对象当然也有一个  _ proto _,引用着它的原型对象,就这样层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为原型链的结束.

也就是我们常见的

let a = []; a._proto_ = Array.prototype // 所以a可以调用有数组方法 复制代码

看不懂没关系,我们慢慢来解析上边这句话\

1.一个新名词原型对象

首先原型对象顾名思义就是一个对象,所以我们可以对这个对象的属性进行 修改 增加等操作

// 覆写之前的Array.find() 函数 Array.prototype.find = function(){ } // 添加属性 Array.prototype.myAttr = 'test' 复制代码

那么问题来了,这个原型对象在什么时候创建的?又在何处引用呢?
js 里除了每个对象有_proto_属性外,每个函数在创建时都附带创建一个原型对象(保存在堆中),而对此原型对象的引用就保存在函数的 prototype 属性中(别忘了函数也是对象)

2. 构造函数

js函数都可以作为构造函数,因此这里的构造函数,也可以理解为new了一个对象的函数

function myFun(num){     const  a = 0;     const b = {};     this.c = num;      } let myObj = new myFun(2); myObj._proto_ = myFun.prototype 复制代码

3.为什么要指向构造函数的原型对象呢

因为原型对象中,存储的就是可以复用与继承的属性与方法 !
这是不是类似于我们抽象出来的超类或者父类?\

所以通过_proto_能访问到其构造函数的原型对象,也就能获取到可以继承的属性与方法,比如 数组的length属性的get,数组的find() every() 方法等

 let arr = [1,2,3,4,6];  console.log(arr.length); 复制代码

当你访问arr.length,发现并没有这个length 属性,就通过_proto_找到arr的原型对象,也就是Array.prototype,再找一找length,找到了! 如果依旧没找到,继续通过_proto_找到原型对象... 大部分最终都会到Object.prototype._ proto _ = null ,也就结束了.

image.png

  1. 每个对象都有 __ proto __ 属性,但只有函数对象才有 prototype 属性

  2. constructor属性,只有 prototype对象 才有这个属性,这个属性很简单,就是从prototype对象指向构造函数,而构造函数的peototype属性是从构造函数指向prototype对象,相对应.而其它对象的constructor属性(比如你声明的arr 也有constructor属性)都是通过__proto__对象从prototype对象继承而来。

  3. 函数在创建时,JS会为该函数创建一个对应的prototype对象,而这个prototype对象的constructor属性又指向该函数,即Foo.prototype.constructor === Foo


作者:零念念
链接:https://juejin.cn/post/7039166117314560030


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐