prototype、constructor、_ _ proto _ _各自的链式结构梳理

264 阅读2分钟

一切都是根据这张图展开的思考,这是一个最基础的原型链构成

image.png 相应的代码很简单:

function Foo() {...};
let f1 = new Foo();

既然每两个相邻对象或函数之间的关系只可能有prototype、constructor、_ _ proto _ _ 三种,那么这三种联系能不能分别各自构成链式结构呢?

1. prototype

因为只有构造函数有prototype,prototype指向其原型对象就停了,所以prototype不能构成链式结构

2. constructor

除了null所有东西都有constructor,constructor指向构造函数,constructor链的终点是Function(),Function()自己的constructor就是他自己

实例f1 -> Foo() -> Function()

Foo.prototype -> Foo() -> Function()

Function.prototype -> Function()

Object.prototype -> Object() -> Function()

3. _ _ proto _ _

_ _ proto _ _ 构成的就是传说中的原型链,在本例中原型链可以分为实例的原型链以及构造函数的原型链

实例f1 -> Foo.prototype -> Object.prototype -> null

所有构造函数 -> Function.prototype -> Object.prototype -> null

之前一直对原型对象没有一个直接的理解,所以试着控制台输出了一下,下图是Foo.prototype,可以看出Foo的原型对象其实也就是一个仅包含constructor和[[Prototype]]两个隐藏属性的普通对象罢了,完全没有那么神秘嘛!

image.png

再来看看下图的Object.prototype,发现Object的原型对象甚至只有一个constructor属性,并且这个constructor就是Object自己。Object的原型对象没有再往上的[[Prototype]]了,这就是原型链的终点。

image.png

还有一个小疑惑: 同样是查询Object的原型对象中不存在的属性,为什么__proto__是null,而其他其他的普通字段会返回undefined呢?

image.png

我目前的理解:undefined是被动生成的空,null是主动赋值的空

难度进阶

如果两个类间有继承关系,那么原型链又会长什么样呢?上图:

image.png