JavaScript 的原型链是其实现继承和属性共享的核心机制,理解原型链需要从对象、构造函数、原型对象之间的关系入手。
首先要认清几个基本概念
- 对象(Object):就是具体的数据,比如
{ name: "小明" } - 构造函数(Constructor): 用来创建对象的“模板函数”,比如
function Person() {}。 - 原型对象(Prototype):一个特殊的对象,用来存放共享的属性和方法,比如
Person.prototype。
核心原理:原型链如何工作
1. 原型链的本质:对象之间的“继承链”
- 每个对象都有一个隐藏属性
[[Prototype]](可以通过__proto__或Object.getPrototypeOf()访问),指向它的“原型对象”。 - 原型对象本身也是对象,它也有自己的
[[Prototype]],这样层层链接,直到最终指向null,形成一条链。 -
// 创建一个对象 const obj = { name: "小明" }; // 原型链:obj → Object.prototype → null console.log(obj.__proto__ === Object.prototype); // true console.log(Object.prototype.__proto__); // null
2. 构造函数和原型的关系
- 构造函数有一个
prototype属性,指向它的原型对象。 - 实例对象通过
new调用构造函数创建,其__proto__指向构造函数的prototype。 -
function Person(name) { this.name = name; } // 实例对象 const person1 = new Person("小明"); // 原型链关系 console.log(person1.__proto__ === Person.prototype); // true console.log(Person.prototype.__proto__ === Object.prototype); // true
3. 属性查找机制:逐级向上找
当访问对象的属性时:
- 先找自己:对象自身是否有这个属性?
- 找不到就向上找原型:沿着
__proto__链一层层向上查找。 - 直到终点:如果找到
null还没找到,返回undefined。
function Person() {}
Person.prototype.sayHello = function() {
console.log("Hello!");
};
const person1 = new Person();
person1.sayHello(); // 调用的是原型上的方法!
console.log(person1.toString()); // 来自 Object.prototype
实际应用:为什么原型链重要?
实现方法共享(省内存)
- 所有实例共享原型上的方法,而不是每个实例单独创建。
function Dog(name) {
this.name = name;
}
// 方法放在原型上
Dog.prototype.bark = function() {
console.log("汪汪!");
};
const dog1 = new Dog("小黑");
const dog2 = new Dog("小白");
dog1.bark(); // 共享同一个 bark 方法
实现继承
- 子类继承父类:通过让子类的原型指向父类的实例。
- 经典继承示例:
// 父类 function Animal() { this.type = "动物"; } Animal.prototype.eat = function() { console.log("吃东西"); }; // 子类 function Dog() { Animal.call(this); // 调用父类构造函数,继承属性 } Dog.prototype = Object.create(Animal.prototype); // 继承方法 Dog.prototype.constructor = Dog; // 修正 constructor 指向 const dog = new Dog(); dog.eat(); // "吃东西"(来自父类原型) console.log(dog.type); // "动物"(来自父类构造函数)
修改内置对象
- 可以通过修改原型,给所有内置对象(如数组、字符串)添加方法。
// 给所有数组添加一个求和方法 Array.prototype.sum = function() { return this.reduce((total, num) => total + num, 0); }; const arr = [1, 2, 3]; console.log(arr.sum()); // 6
- THE END -
最后修改:2025年3月24日
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://mi-blog.cn/index.php/2022/11/24/%e8%b0%88%e8%b0%88js%e5%8e%9f%e5%9e%8b%e9%93%be/
共有 0 条评论