原型与原型链
每个函数都有 prototype 属性,除了 Function.prototype.bind(),该属性指向原型。
每个对象都有 proto 属性,指向了创建该对象的构造函数的原型。其实这个属性指向了 [[prototype]],但是 [[prototype]] 是内部属性,我们并不能访问到,所以使用 proto 来访问。
对象可以通过 proto 来寻找不属于该对象的属性,proto 将对象连接起来组成了原型链。
文章图片
prototype
首先来介绍下 prototype 属性。这是一个显式原型属性,只有函数才拥有该属性。基本上所有函数都有这个属性,但是也有一个例外
let fun = Function.prototype.bind()
如果你以上述方法创建一个函数,那么可以发现这个函数是不具有 prototype 属性的。
prototype 如何产生的 当我们声明一个函数时,这个属性就被自动创建了。
function Foo() {}
并且这个属性的值是一个对象(也就是原型),只有一个属性
constructor
文章图片
constructor
对应着构造函数,也就是 Foo
。_ proto _
这是每个对象都有的隐式原型属性,指向了创建该对象的构造函数的原型。其实这个属性指向了 [[prototype]],但是 [[prototype]] 是内部属性,我们并不能访问到,所以使用 proto 来访问。
因为在 JS 中是没有类的概念的,为了实现类似继承的方式,通过 proto 将对象和原型联系起来组成原型链,得以让对象可以访问到不属于自己的属性。
【原型与原型链】实例对象的 proto 如何产生的
从上图可知,当我们使用 new 操作符时,生成的实例对象拥有了 proto属性。
function Foo() {}
// 这个函数是 Function 的实例对象
// function 就是一个语法糖
// 内部调用了 new Function(...)
所以可以说,在 new 的过程中,新对象被添加了 proto 并且链接到构造函数的原型上。
new 的过程
- 新生成了一个对象
- 链接到原型
- 绑定 this
- 返回新对象
在调用 new 的过程中会发生以上四件事情Function.proto === Function.prototype
个人的理解是:其他所有的构造函数都可以通过原型链找到 Function.prototype ,并且 function Function() 本质也是一个函数,为了不产生混乱就将 function Function() 的 proto 联系到了 Function.prototype 上。总结
- Object 是所有对象的爸爸,所有对象都可以通过 proto 找到它
- Function 是所有函数的爸爸,所有函数都可以通过 proto 找到它
- Function.prototype 和 Object.prototype 是两个特殊的对象,他们由引擎来创建
- 除了以上两个特殊对象,其他对象都是通过构造器 new 出来的
- 函数的 prototype 是一个对象,也就是原型
- 对象的 proto 指向原型, proto 将对象和原型连接起来组成了原型链
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- Docker应用:容器间通信与Mariadb数据库主从复制
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 第326天
- Shell-Bash变量与运算符
- 画解算法(1.|画解算法:1. 两数之和)
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- 逻辑回归的理解与python示例
- Guava|Guava RateLimiter与限流算法
- 「#1-颜龙武」区块链的价值是什么()