JavaScript 的原型和原型链是其继承机制的核心。以下通过具体示例逐步说明:
一、原型(Prototype)
每个 JavaScript 对象都有一个隐藏的 [[Prototype]] 属性(可通过 __proto__ 或 Object.getPrototypeOf() 访问),指向它的原型对象。
示例 1:对象的原型
const animal = {
type: "Unknown",
sound() {
console.log("Makes a sound");
}
};
const dog = {
breed: "Husky"
};
// 设置 dog 的原型为 animal
Object.setPrototypeOf(dog, animal);
console.log(dog.type); // "Unknown"(来自原型 animal)
dog.sound(); // "Makes a sound"(来自原型 animal)
dog对象本身没有type和sound,但通过原型链访问到了animal的属性和方法。
二、构造函数的原型
函数在创建时自动获得一个 prototype 属性,指向一个对象。当用 new 创建实例时,实例的 [[Prototype]] 会指向该对象。
示例 2:构造函数与原型
function Person(name) {
this.name = name;
}
// 向构造函数的原型添加方法
Person.prototype.sayHello = function() {
console.log(`Hello, I'm ${this.name}`);
};
const alice = new Person("Alice");
alice.sayHello(); // "Hello, I'm Alice"
console.log(Object.getPrototypeOf(alice) === Person.prototype); // true
alice是Person的实例,它的原型指向Person.prototype。sayHello方法定义在Person.prototype上,所有实例共享它。
三、原型链(Prototype Chain)
当访问对象的属性时,JavaScript 会沿着原型链逐级查找,直到找到属性或到达链的末端(null)。
示例 3:多层原型链
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function() {
console.log(`${this.name} is eating.`);
};
function Dog(name, breed) {
Animal.call(this, name); // 调用父类构造函数
this.breed = breed;
}
// 设置 Dog.prototype 的原型为 Animal.prototype
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog; // 修复构造函数指向
Dog.prototype.bark = function() {
console.log("Woof!");
};
const myDog = new Dog("Buddy", "Golden Retriever");
myDog.eat(); // "Buddy is eating."(来自 Animal.prototype)
myDog.bark(); // "Woof!"(来自 Dog.prototype)
// 原型链:myDog → Dog.prototype → Animal.prototype → Object.prototype → null
myDog的原型链:myDog自身有name和breed。myDog.__proto__指向Dog.prototype(包含bark方法)。Dog.prototype.__proto__指向Animal.prototype(包含eat方法)。Animal.prototype.__proto__指向Object.prototype(包含toString等方法)。- 最终指向
null,结束查找。
四、关键点总结
-
原型:
- 每个对象都有一个原型(
[[Prototype]])。 - 构造函数通过
prototype属性为实例提供共享方法和属性。
- 每个对象都有一个原型(
-
原型链:
- 访问属性时,JavaScript 沿原型链向上查找。
- 原型链的终点是
Object.prototype.__proto__(即null)。
-
继承实现:
- 通过
Object.create()或修改__proto__建立原型链。 - 构造函数中调用父类构造函数(如
Animal.call(this))实现属性继承。
- 通过
五、验证原型链的工具方法
// 检查对象是否是另一个对象的原型
console.log(Animal.prototype.isPrototypeOf(myDog)); // true
// 查看对象的原型
console.log(Object.getPrototypeOf(myDog)); // Dog.prototype
通过理解原型和原型链,可以更好地掌握 JavaScript 的继承机制和对象设计模式。
&spm=1001.2101.3001.5002&articleId=145573665&d=1&t=3&u=23cce08f28bf43deb50b680c1b184ebc)
391

被折叠的 条评论
为什么被折叠?



