概念
当声明一个函数(一般只有构造函数我们会关注原型);
内存中会创建一个对象,每个函数的 prototype 指向这个对象,这个对象即 原型对象(简称原型);
function Person() {}
Person.prototype.fn = function () {}
原型对象的构造器 constructor 指向构造函数本身,包含 length name arguments 等静态方法和属性。
Person.prototype.constructor === Person
显式 / 隐式原型
每一个函数 / 类 均有显式原型 prototype;
所有实例均有隐式原型 __proto__ 指向其构造函数的 prototype;
new 实例并没有 prototype 属性,通过__proto__访问到构造函数 Person的原型对象;
function Person() {}
const p = new Person()
console.log(p.__proto__ === Person.prototype); // true
值类型没有
__proto__ ,但它依然可访问 API,因为 JS 会先将它包装为引用类型,然后触发 API
const obj = {}; // 相当于 new Object()
console.log(obj.__proto__ === Object.prototype);
原型链
一个对象的 __proto__ 指向它构造函数的 prototype ,而 prototype 本身也是一个对象,也会指向它构造函数的 prototype ,于是就形成了原型链;
instanceof 本质是实例的隐式原型 __proto__ 往原型链上寻找是否有能匹配的显式原型。
class Person {}
Person.prototype.sayHello = function () {
console.log('hello')
}
class Student extends Person {}
const s = new Student()
子类(Student)的原型对象会创建一个隐式原型__proto__指向父类的原型对象
Array、String、Boolean ...... 等等顶层原型均 Object
而 Object 本身的原型对象的隐式原型 __proto__ 指向 null