关于 prototype-pattern
一项介绍 JavaScript 原型模式的技能,讲解如何让多个对象共享属性和方法。内容涵盖 ES6 类、原型链、继承及 Object.create()。
主要功能
- 01通过原型共享方法
- 02使用 ES6 类和 extends
- 03用 Object.create() 创建对象
- 04理解原型链查找
- 05避免实例方法重复
适用场景
- 01让多个实例共享方法
- 02建模对象类型间的继承
- 03学习 JavaScript 原型查找机制
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ patternsdev/ skills --skill prototype-pattern安装后在 Claude Code 中输入/prototype-pattern确认已加载。
详细介绍
原型模式
原型模式是一种在许多同类型对象之间共享属性的实用方式。原型是 JavaScript 原生支持的对象,对象可以通过原型链访问它。
在应用中,我们经常需要创建许多同类型对象。一种实用的做法是创建 ES6 类的多个实例。
适用场景
- 当许多对象需要访问相同的方法,而不想重复定义这些方法时,可以使用此模式
- 这有助于理解 JavaScript 的继承模型和 ES6 类
使用说明
- 使用 ES6 类自动将方法添加到原型上
- 使用
Object.create()创建具有特定原型的对象 - 利用原型链实现继承(ES6 类中的
extends关键字) - 了解原型上的属性由所有实例共享,不会为每个实例单独复制
详情
假设我们想创建许多狗!在这个示例中,狗能做的事情不多:它们只有名字,还会叫!
class Dog {
constructor(name) {
this.name = name;
}
bark() {
return `Woof!`;
}
}
const dog1 = new Dog("Daisy");
const dog2 = new Dog("Max");
const dog3 = new Dog("Spot");
请注意,constructor 中包含一个 name 属性,而类本身包含一个 bark 属性。使用 ES6 类时,所有在类本身定义的属性(本例中的 bark)都会自动添加到 prototype 上。
我们可以通过访问构造函数上的 prototype 属性,或通过任意 实例 上的 __proto__ 属性,直接查看 prototype。
console.log(Dog.prototype);
// constructor: ƒ Dog(name, breed) bark: ƒ bark()
console.log(dog1.__proto__);
// constructor: ƒ Dog(name, breed) bark: ƒ bark()
构造函数任意实例上的 __proto__ 值都直接引用该构造函数的原型!每当我们尝试访问对象上不存在的属性时,JavaScript 就会沿着原型链向下查找,确认该属性是否存在于原型链中。
在处理需要访问相同属性的对象时,原型模式非常强大。我们无需每次都创建该属性的副本,只需将属性添加到原型上,因为所有实例都可以访问原型对象。
由于所有实例都可以访问原型,因此即使创建实例之后,也很容易向原型添加属性。
假设我们的狗不只能叫,还能玩!我们可以通过向原型添加 play 属性来实现。
原型链这一术语表示查找过程可能不止一步。确实如此!到目前为止,我们只看到如何访问 __proto__ 所引用的第一个对象上直接可用的属性。不过,原型本身也有一个 __proto__ 对象!
再创建另一种狗:超级狗!这种狗应该继承普通 Dog 的所有内容,同时还能飞。我们可以扩展 Dog 类并添加一个 fly 方法,从而创建超级狗。
class SuperDog extends Dog {
constructor(name) {
super(name);
}
fly() {
return "Flying!";
}
}
由于扩展了 Dog 类,我们可以访问 bark 方法。SuperDog 原型上的 __proto__ 值指向 Dog.prototype 对象!
现在就能明白它为什么叫原型_链_了:当我们尝试访问对象上没有的属性时,JavaScript 会递归地沿着 __proto__ 指向的所有对象向下查找,直到找到该属性!
Object.create
Object.create 方法可以创建一个新对象,并允许我们显式指定其原型的值。
const dog = {
bark() {
return `Woof!`;
},
};
const pet1 = Object.create(dog);
虽然 pet1 本身没有任何属性,但它可以访问原型链上的属性!由于我们将 dog 对象传给了 pet1 作为其原型,因此可以访问 bark 属性。
Object.create 是一种简单的方式,可以通过指定新创建对象的原型,让对象直接继承其他对象的属性。新对象可以沿着原型链访问这些属性。
原型模式让对象可以轻松访问并继承其他对象的属性。由于原型链允许我们访问并非直接定义在对象自身上的属性,因此可以避免重复定义方法和属性,从而减少内存占用。