回答
- 原型链的设计目的,是为了实现对象的复制,原理是一个对象可以使用其原型链上所有的变量和方法。
- 对象被大体分为三类,原型对象,实例对象,构造函数。三者通过prototype、proto、constructor、new相互关联。
原型对象通过
__proto__构成的链,称为原型链。构造函数也可以通过__proto__构成链。分析
原型、构造函数、实例的关系
原型是一种特殊的对象,包含一些特殊的key。
- 构造函数是一种特殊的函数,可以执行并返回一个实例对象。
- 实例是一个普通对象。
原型链、构造函数链
- 原型的上面是原型,组成了一条原型链。
- 构造函数的上面是构造函数,组成了一条构造函数链。
- 在终点处有特殊机制(设计缺陷)防止造成循环,这个特殊机制就是 Function.proto===Function.prototype,这个机制保证了终点是 null。
举个例子:
// @ts-nocheckclass A {}class B extends A {}class C extends B {}console.log(typeof A, // functiontypeof A.prototype, // objectC.__proto__ === B, // true,函数的上面是函数B.__proto__ === A, // trueA.__proto__ === Function, // false,终点特殊处理A.__proto__ === Function.prototype, // 终点特殊处理,不再指向Function,而指向Function的原型// 但 typeof Function.prototype === "function"C.prototype.__proto__ === B.prototype, // true,原型的上面是原型B.prototype.__proto__ === A.prototype, // trueA.prototype.__proto__ === Object.prototype, // trueObject.prototype.__proto__ === null // 终点为null);
原型链是原型的链,顶层为 null
这句话虽然有一些直白,但却可以直接揭示其本质。
我们从一组代码看起,大家可以在浏览器中跑一跑,每行会输出什么?
Object.prototype.__proto__; // null
Function.prototype.__proto__.__proto__; // null
String.prototype.__proto__.__proto__; // null
class A {}
class B extends A {}
class C extends B {}
A.prototype.__proto__.__proto__; // null
B.prototype.__proto__.__proto__.__proto__; // null
C.prototype.__proto__.__proto__.__proto__.__proto__; // null
以上所有的输出均为 null,我们可以用图例表示:
【此处等待补充一张图】
以最后一条为例,文字说明
C.prototype是「C原型」C.prototype.__proto__是「B原型」C.prototype.__proto__.__proto__是「A原型」C.prototype.__proto__.__proto__.__proto__是「Object原型」C.prototype.__proto__.__proto__.__proto__.__proto__是「null」
instanceof,isPrototypeOf
inatanceof 针对 function,其右边必须是一个 fucntion;isPrototypeOf 针对 object,其调用者必须是一个 object。
