原型和原型链之**由浅入深**
2023-10-22 20:52:57
在上一篇文章中,我们讨论了构造函数的概念。我们知道,构造函数是用来创建新对象的函数。当我们使用new运算符调用构造函数时,它会创建一个新对象,并将该对象的原型设置为构造函数的prototype属性。原型是一个对象,它包含了所有实例共享的属性和方法。原型链是对象从其原型继承属性和方法的链。
原型
每个构造函数都有一个prototype属性,该属性指向一个对象,这个对象就是该构造函数的原型。原型对象包含了所有实例共享的属性和方法。这意味着,当我们创建新对象时,该对象将自动继承其构造函数原型的所有属性和方法。
例如,以下代码创建了一个Person构造函数:
function Person(name) {
this.name = name;
}
Person构造函数的prototype属性指向一个对象,该对象包含了所有Person实例共享的属性和方法。我们可以使用以下代码访问Person构造函数的原型对象:
Person.prototype;
Person构造函数的原型对象包含以下属性和方法:
{
constructor: Person,
sayHello: function() {
console.log(`Hello, my name is ${this.name}.`);
}
}
原型链
原型链是对象从其原型继承属性和方法的链。当我们访问对象的属性或方法时,JavaScript会首先在该对象中查找该属性或方法。如果该对象中没有该属性或方法,JavaScript会沿着原型链向上查找,直到找到该属性或方法。
例如,以下代码创建了一个Person对象:
const person = new Person('John');
person对象从其构造函数Person继承了name属性和sayHello方法。我们可以使用以下代码访问person对象的name属性和sayHello方法:
person.name; // "John"
person.sayHello(); // "Hello, my name is John."
如果我们尝试访问person对象的age属性,JavaScript会首先在person对象中查找age属性。由于person对象中没有age属性,JavaScript会沿着原型链向上查找,直到找到age属性。Person构造函数的原型对象中没有age属性,因此JavaScript会返回undefined。
person.age; // undefined
原型链是一个非常强大的机制,它允许我们共享代码和重用代码。例如,我们可以创建一个Animal构造函数,该构造函数包含所有动物共享的属性和方法。然后,我们可以创建一个Dog构造函数,该构造函数从Animal构造函数继承属性和方法。Dog构造函数可以添加一些额外的属性和方法,这些属性和方法是Dog特有的。
function Animal() {
this.name = name;
}
Animal.prototype.eat = function() {
console.log(`I am eating.`);
};
function Dog(name, breed) {
this.name = name;
this.breed = breed;
}
Dog.prototype = new Animal();
Dog.prototype.bark = function() {
console.log(`Woof! Woof!`);
};
const dog = new Dog('Buddy', 'Golden Retriever');
dog.name; // "Buddy"
dog.breed; // "Golden Retriever"
dog.eat(); // "I am eating."
dog.bark(); // "Woof! Woof!"
总结
原型和原型链是JavaScript中非常重要的概念。理解原型和原型链可以帮助我们更好地理解JavaScript是如何工作的。原型链允许我们共享代码和重用代码,这使得JavaScript成为一种非常灵活和强大的编程语言。