在 JavaScript 中,原型和原型链是理解对象和继承机制的关键概念。
原型(Prototype)
在 JavaScript 中,每个对象都有一个内部属性 [[Prototype]]
(在代码中通常通过 __proto__
访问),这个属性引用了另一个对象,我们称之为原型。原型对象可以包含属性和方法,这些属性和方法可以被原型链上的其他对象共享。
创建对象的原型
你可以通过几种方式创建对象的原型:
-
对象字面量:
const person = { name: 'Alice', greet() { console.log(`Hello, my name is ${this.name}`); } };
-
构造函数:
function Person(name) { this.name = name; } Person.prototype.greet = function() { console.log(`Hello, my name is ${this.name}`); }; const alice = new Person('Alice');
-
Object.create() 方法:
const personProto = { greet() { console.log(`Hello, my name is ${this.name}`); } }; const alice = Object.create(personProto); alice.name = 'Alice';
原型链(Prototype Chain)
原型链是对象查找属性或方法的机制。当访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript 引擎会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的末端(通常是 Object.prototype
)。
使用原型链
当你尝试访问一个对象的属性或方法时,JavaScript 引擎会按照以下步骤查找:
- 检查对象本身是否有该属性或方法。
- 如果没有,检查对象的
[[Prototype]]
属性(即__proto__
)。 - 如果
[[Prototype]]
属性指向的对象也没有该属性或方法,继续向上查找[[Prototype]]
的[[Prototype]]
。 - 这个过程会一直持续,直到找到属性或方法,或者到达原型链的末端。
示例
const personProto = {
greet() {
console.log('Hello!');
}
};
const alice = Object.create(personProto);
alice.name = 'Alice';
console.log(alice.name); // Alice
alice.greet(); // Hello!
// 查找属性 'name'
// 1. alice 对象本身有 'name' 属性,直接返回 'Alice'
// 查找方法 'greet'
// 1. alice 对象本身没有 'greet' 方法
// 2. 查找 alice 的原型 personProto,找到 'greet' 方法,执行
注意事项
- 原型链查找是单向的,只能向上查找,不能向下。
- 原型链的末端通常是
Object.prototype
,它包含了一些基本的方法,如toString()
、hasOwnProperty()
等。 - 直接修改原型对象会影响到所有基于该原型创建的对象。
通过理解原型和原型链,你可以更好地控制对象的继承和共享属性,从而编写更高效和可维护的 JavaScript 代码。如果你有任何疑问或需要进一步的示例,随时告诉我!