Fork me on Gitee

JavaScript原型及原型链

JavaScript 中除了基础类型外的数据类型,都是对象(引用类型)。但是由于其没有 类(class,ES6 引入了 class,但其只是语法糖)的概念,如何将所有对象联系起来就成立一个问题,于是就有了原型和原型链的概念。


每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节

img

上面是 MDN里有关原型链知识 的摘录,什么意思?让我们来解释一下

事实上 JavaScript 所有数据都可以以对象的形式表现:由于函数是对象,我们可以用构造函数的方法使得 Number、Boolean、String 变成对象。

下面以 Number 为例 (其他类型也一样)

可以用 var 基本类型 = new 对应基本类型的函数() 的方法创建一个新函数

var n = new Number() 创建一个 Number 函数,其是一个对象

img

这里的 n 就是 Number 的实例对象,可以看到 n 里面有一个 proto 指向 Number 所指向的原型对象(也是 n 自己本身的原型对象),Number 为 n 的构造函数,它通过 prototype 指向自己的原型对象,而后又可以通过 constructor 指向回 Number 本身;

而 Number 函数也有一个 proto 指向 Object 这个构造函数的原型对象,Object 通过 prototype 指向自己原型对象 ;

Object 函数没有 proto,证明其已经到达最后的属性层,他的 proto 指向为 null。

img原型链

以上一整个原型与原型层层相链接的过程即为原型链

其可以将公用属性存放在同一原型层中,实现继承、节省内存空间等。

当您访问实例的属性时,JavaScript 首先会检查它们是否直接存在于该对象上,如果不存在,则会 [[Prototype]] 中查找。这意味着你在 prototype 中定义的所有内容都可以由所有实例有效共享,你甚至可以稍后更改部分 prototype,并在所有现有实例中显示更改(如果需要)。


通过以上例子我们可以得到下面两个“公式”

var 对象 = new 函数()

对象.proto === 对象的构造函数.prototype

我们已经知道

var n = new Number()

n.proto === Number.prototype //true

那么 Number.proto

Number 的构造函数是 Function,即 Number 是 Function 的实例

即有 Number.proto === Function.prototype

那么同理

var object = new Object()

object.proto === Object.prototype

Object.proto === Function.prototype

再进一步推断

var function = new Function()

function.proto === Function.prototype

Function.proto === Function.prototype

img

posted @ 2021-07-16 17:33  等风的羽毛  阅读(62)  评论(0编辑  收藏  举报
1