编辑
2025-02-26
前端
00
请注意,本文编写于 73 天前,最后修改于 66 天前,其中某些信息可能已经过时。

目录

1. 原型概念
2. 基本原型三角
3. 对象原型三角
4. 函数原型三角
5. 函数和对象的原型关系
6. 原型的全貌

原型的概念还是非常复杂且容易令人产生错误的,本文第一版就有很多错误概念,这里再修改后,就相对少多了 (应该吧,欢迎指出错误)

1. 原型概念

JS 是一门基于原型的语言,其他语言通过类描述和实例化对象,JS 通过构造函数描述和实例化对象,通过原型实现对象继承。

JS 中几乎每个对象都有隐式原型 __proto__,相当于他的父对象,但是基本没有显式原型 prototype (除了函数),这里的对象可以是普通的对象、也可以是函数等,他们都会继承有其他的东西

每个构造函数上都有一个显式原型,用于描述创建的对象的属性和行为,对象的隐式原型等于它构造函数的显式原型

当对象上找不到某个属性时,他就会往原型上寻找,原型上没有就会向原型的原型上寻找,这也就是原型链的基本概念

2. 基本原型三角

  • 创建一个函数 A,在 A 中使用 this 描述要创建的对象的属性和方法,prototype 描述在创建的对象上继承的属性和方法,修改 prototype 会影响所有实例化的对象
  • 实例化对象可以通过 contructor 获取到构造函数的引用,通过 __proto__ 获取到原型
  • 函数 A 的原型的构造函数实际上是函数 A 本身
js
function A() {} const f1 = new A(); // __proto__ 的引用和 prototype 的引用是相等的,但是如果修改了prototype,__proto__ 的引用不会改变 f1.__proto__ === A.prototype; // true // f本身是没有constructor属性的,它是通过原型链找到的 f1.__proto__.constructor === A; // true // 如果修改prototype是一个有原型的对象,新的实例化对象的构造函数不指向A function B() {} A.prototype = { constructor: B, }; const f2 = new A(); f2.__proto__.constructor === A; // false f2.__proto__.constructor === B; // true // 因为f1.__proto__ 还是原来那个对象,所以f1的构造函数还是A f1.__proto__.constructor === A; // true

3. 对象原型三角

  • 任何一个没有其他继承关系的对象的隐式原型,都是 [Object: null prototype]{},而他的隐式原型最终会指向 null,这也就得到了原型链的终点 null
  • Object 构造函数的显式原型是 [Object: null prototype]{}
js
const obj1 = new Object() obj1.__proto__ // [Object: null prototype] {} obj1.__proto__ === Object.prototype // true obj1.__proto__.__proto__ // null obj1.__proto__.constructor === Object // true

注:在浏览器控制台可以打印对象结构,以下是各个对象的结构

  • Object
  • 实例化对象 obj1
  • obj1 的隐式原型/ Object 的显式原型

4. 函数原型三角

函数的构造函数和实例化函数之间的关系也比较特殊

  • Function 的显式原型和隐式原型是同一个函数,这个函数的 constructor 指向 Function
  • 实例化函数 f 默认自带一个显式原型,这和普通的实例化对象不一样,同时这个显式原型自带一个 constructor 指向 f
  • f 的隐式原型等于 Function 的原型

注:在浏览器控制台可以打印对象结构,以下是各个对象的结构

  • Function
  • 实例化函数 f
  • Function 的原型函数
  • f 的显式原型 prototype

5. 函数和对象的原型关系

除了函数本身的原型关系,它的原型和对象也有一定的原型关系

js
Function.prototype // f () { [native code] } Function.__proto__ === Function.prototype // true Function.__proto__.constructor === Function // true Function.__proto__.__proto__ // [Object: null prototype] {} Object.__proto__ // f () { [native code] } Object.__proto__ === Function.prototype // true Object.__proto__.constructor === Function // true

6. 原型的全貌

根据上面的分析,就可以得出原型的全貌图了,直接看的话还是太抽象了,可以拆开分析,使用代码验证。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:pepedd864

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!