每个 JavaScript 对象(除了 null)在创建时都有一个与之关联的对象,这个对象称为原型(prototype)。每个函数都有一个 prototype 属性,该属性是一个对象,用于为构造函数创建的实例提供共享的属性和方法。
示例:
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log('Hello, ' + this.name);
};
const alice = new Person('Alice');
alice.greet(); // 输出: Hello, Alice
在这个示例中,Person 构造函数的 prototype 属性被设置了一个 greet 方法,所有由 Person 构造函数创建的实例都可以访问这个方法。
当访问对象的属性或方法时,JavaScript 引擎首先在对象自身的属性中查找。如果找不到,则会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的顶端(即 Object.prototype),如果仍然找不到,则返回 undefined。
示例:
const obj = {
a: 1
};
const obj2 = Object.create(obj);
obj2.b = 2;
const obj3 = Object.create(obj2);
obj3.c = 3;
console.log(obj3.a); // 输出: 1
console.log(obj3.b); // 输出: 2
console.log(obj3.c); // 输出: 3
在这个示例中,obj3 通过原型链依次查找属性 a、b 和 c。
构造函数和原型:
prototype 属性,它指向一个对象,该对象包含由该构造函数创建的实例共享的属性和方法。Person.prototype.greet 是所有 Person 实例共享的方法。原型对象:
constructor 属性,指回关联的构造函数。Person.prototype.constructor 指向 Person 构造函数。原型链机制:
obj3 没有 a 属性,因此沿原型链查找 obj2 和 obj 直到找到 a 属性。Object.prototype:
Object.prototype,这是原型链的顶端。Object.prototype 上定义了一些通用的方法,如 toString、hasOwnProperty 等。理解 JavaScript 中的原型和原型链对掌握对象继承和属性查找机制至关重要。通过构造函数、原型对象和原型链的概念,可以更有效地组织和复用代码。