原型原型链

原型原型链

原型

每个 JS 对象(除 null)都有一个隐藏的 [[Prototype]] 属性,指向它的“原型对象”(简称原型)

原型对象也是一个普通对象,它包含可以被其他对象共享的属性和方法

作用:存放一些属性和方法 + 在JS中实现继承

image-20250419084957083

原型链

可以通过实例对象的 __proto__ 属性访问原型

1
2
3
4
const arr = new Array(1, 2, 3)
arr.reverse() // 翻转
arr.sort() // 排序 // 这些方法都是挂载到Array.prototype上的,可以共享给所有的数组实例使用
console.log(Array.prototype === arr.__proto__); // true

所有原型对象的终点是null

原型链的顶端通常是 Object.prototype

当访问一个对象的属性或方法时,JS 会沿着对象的原型链逐级向上查找,直到找到该属性或到达原型链的终点(null)。

image-20250419085919620
1
2
const obj = {};
console.log(Object.prototype.__proto__); // null
1
2
3
arr.__proto__				//指向Array.prototype
Array.prototype.__proto__ //指向Object.prototype(Array.prototype也是对象,所以也有.__proto__)
Object.prototype.__proto__ //指向null

属性查找会自动沿着原型链进行

1
2
3
4
5
6
7
8
9
10
11
function Person(name) { // 构造函数
this.name = name;
}

Person.prototype.greet = function () { // 原型上的方法
console.log(`Hello, my name is ${this.name}.`);
};

const alice = new Person('Alice'); // 实例

console.log(alice.greet === alice.__proto__.greet); // true // 都指向原型

当你写 alice.greet()

首先检查 alice 对象本身是否有 greet 属性

如果没有,则继续检查 alice.__proto__(即 Person.prototype

如果在 alice.__proto__ 上找到了 greet 方法,则调用它,*并将 this 绑定到 alice*

实际上,alice.greet() 是一种语法糖,等价于 alice.__proto__.greet.call(alice)

所以直接推荐使用 alice.greet() 而省略 __proto__