什么是原型?
在 JavaScript 中,原型是一个对象。每个 JavaScript 对象都有一个原型,当你访问对象的属性或方法时,JavaScript 首先会检查对象本身是否有这个属性或方法。如果没有,它会去这个对象的原型上查找,再往上查找原型的原型,以此类推,直到找到或者到达原型链的末尾(null
)。
举个例子
想象一下,我们有一个 动物
(Animal)这个类(可以看作一个对象):
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(this.name + ' makes a noise.');
};
在这个例子中:
- 构造函数:
Animal
是一个构造函数,我们可以通过它创建一些动物对象。 - 原型:
Animal.prototype
就是 Animal 的原型,里面有一个方法speak
。这个方法是所有通过Animal
创建的对象共享的。
创建一个动物对象
const dog = new Animal('Dog');
dog.speak(); // 输出: "Dog makes a noise."
当我们调用 dog.speak()
时:
- JavaScript 首先查找
dog
对象中是否有speak
方法。 - 由于
dog
对象没有这个方法,它会去dog
的原型(Animal.prototype
)上查找,找到了,于是调用了这个方法。
什么是原型链?
原型链是一种机制,用于实现这种查找过程。每个对象都有一个指向其原型的内部链接,形成一个链条。链上的每个对象都可以访问其原型上的属性和方法。
示例
继续使用之前的例子,我们可以再扩展一下:
function Dog(name) {
Animal.call(this, name); // 继承 Animal 的属性
}
// 让 Dog 继承 Animal 的原型
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog; // 确保 constructor 的指向正确
Dog.prototype.speak = function() {
console.log(this.name + ' barks.');
};
const dog = new Dog('Buddy');
dog.speak(); // 输出: "Buddy barks."
在这个例子中:
- 原型链:
Dog.prototype
是通过Object.create(Animal.prototype)
继承了Animal
的原型。- 当我们调用
dog.speak()
,JavaScript 首先会查找Dog.prototype
,找到speak
方法,调用它。如果没有找到,它会去Animal.prototype
查找,从而形成了一个原型链。
总结
- 原型:指向一个对象的机制,用来共享属性和方法。像是一个共享的模板。
- 原型链:是通过多个对象的原型相互链接在一起的结构,用来查找属性和方法。
这样就形成了一种层次结构,使得 JavaScript 的对象能够共享属性和行为。你可以想象它们像一棵树,从根部(Object.prototype
)向下延伸,层层分支,每个对象都能访问到它上面的属性和方法。