原型和原型链
在 JavaScript 中,每个对象都有一个原型对象(prototype),原型对象又是一个对象,如果我们在原型对象上添加属性或方法,这些属性和方法会被该原型对象上的所有对象所共享,因为它们都继承自该原型对象。这就是 JavaScript 中的原型(prototype)。
而原型链是指当我们访问一个对象的属性或方法时,如果该对象自身没有该属性或方法,它就会沿着原型链向上查找,直到找到该属性或方法或者查找到原型链的顶端(即 Object.prototype)为止。这个过程就是 JavaScript 中的原型链(prototype chain)。
举个例子,我们定义一个构造函数 Person
:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
const john = new Person('John', 30);
在上述例子中,我们通过 Person 构造函数创建了一个名为 john 的对象,并通过 Person.prototype 对象为 Person 的实例 john 添加了一个 sayHello 方法。当我们调用 john.sayHello() 时,JavaScript 引擎首先会查找 john 对象是否有 sayHello 方法,如果没有,它就会沿着原型链查找,最终找到了 Person.prototype 对象上的 sayHello 方法,然后调用该方法并传入 john 对象作为上下文对象(也就是 this)。
我们可以通过 Object.getPrototypeOf() 方法来查看对象的原型:
console.log(Object.getPrototypeOf(john) === Person.prototype); // true
我们也可以通过 __proto__
属性来访问对象的原型:
console.log(john.__proto__ === Person.prototype); // true
由于原型链的存在,我们还可以给 Person.prototype
的原型对象 Object.prototype
添加方法,从而让 Person 的实例 john 继承该方法:
Object.prototype.sayGoodbye = function() {
console.log('Goodbye!');
};
john.sayGoodbye(); // "Goodbye!"
在上述例子中,当我们调用 john.sayGoodbye()
时,JavaScript 引擎首先在 john
对象上查找 sayGoodbye
方法,发现没有,然后沿着原型链查找,找到了 Object.prototype
对象上的 sayGoodbye
方法,然后调用该方法并传入 john
对象作为上下文对象(也就是 this
)。