prototype-pattern
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePrototype Pattern
原型模式(Prototype Pattern)
The prototype pattern is a useful way to share properties among many objects of the same type. The prototype is an object that's native to JavaScript, and can be accessed by objects through the prototype chain.
In our applications, we often have to create many objects of the same type. A useful way of doing this is by creating multiple instances of an ES6 class.
原型模式(Prototype Pattern)是一种在多个同类型对象之间共享属性的实用方式。原型是JavaScript原生的对象,可通过原型链被其他对象访问。
在我们的应用中,经常需要创建多个同类型的对象。实现这一点的一种实用方式是创建ES6类的多个实例。
When to Use
适用场景
- Use this when many objects need access to the same methods without duplicating them
- This is helpful for understanding JavaScript's inheritance model and ES6 classes
- 当多个对象需要访问相同方法而无需重复定义时使用此模式
- 这有助于理解JavaScript的继承模型和ES6类
Instructions
使用说明
- Use ES6 classes to automatically add methods to the prototype
- Use to create objects with a specific prototype
Object.create() - Leverage the prototype chain for inheritance (keyword in ES6 classes)
extends - Understand that properties on the prototype are shared and not duplicated per instance
- 使用ES6类自动将方法添加到原型中
- 使用创建具有特定原型的对象
Object.create() - 利用原型链实现继承(ES6类中的关键字)
extends - 理解原型上的属性是共享的,不会在每个实例中重复创建
Details
详细说明
Let's say we want to create many dogs! In our example, dogs can't do that much: they simply have a name, and they can bark!
js
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");Notice here how the contains a property, and the class itself contains a property. When using ES6 classes, all properties that are defined on the class itself, in this case, are automatically added to the .
constructornamebarkbarkprototypeWe can see the directly through accessing the property on a constructor, or through the property on any instance.
prototypeprototype__proto__js
console.log(Dog.prototype);
// constructor: ƒ Dog(name, breed) bark: ƒ bark()
console.log(dog1.__proto__);
// constructor: ƒ Dog(name, breed) bark: ƒ bark()The value of on any instance of the constructor, is a direct reference to the constructor's prototype! Whenever we try to access a property on an object that doesn't exist on the object directly, JavaScript will go down the prototype chain to see if the property is available within the prototype chain.
__proto__The prototype pattern is very powerful when working with objects that should have access to the same properties. Instead of creating a duplicate of the property each time, we can simply add the property to the prototype, since all instances have access to the prototype object.
Since all instances have access to the prototype, it's easy to add properties to the prototype even after creating the instances.
Say that our dogs shouldn't only be able to bark, but they should also be able to play! We can make this possible by adding a property to the prototype.
playThe term prototype chain indicates that there could be more than one step. Indeed! So far, we've only seen how we can access properties that are directly available on the first object that has a reference to. However, prototypes themselves also have a object!
__proto____proto__Let's create another type of dog, a super dog! This dog should inherit everything from a normal , but it should also be able to fly. We can create a super dog by extending the class and adding a method.
DogDogflyjs
class SuperDog extends Dog {
constructor(name) {
super(name);
}
fly() {
return "Flying!";
}
}We have access to the method, as we extended the class. The value of on the prototype of points to the object!
barkDog__proto__SuperDogDog.prototypeIt gets clear why it's called a prototype chain: when we try to access a property that's not directly available on the object, JavaScript recursively walks down all the objects that points to, until it finds the property!
__proto__假设我们要创建多只狗!在我们的示例中,狗的能力不多:它们只有一个名字,并且会吠叫!
js
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");注意这里包含属性,而类本身包含属性。使用ES6类时,所有定义在类本身的属性(本例中的)都会自动添加到中。
constructornamebarkbarkprototype我们可以通过访问构造函数的属性,或任何实例的属性直接查看。
prototype__proto__prototypejs
console.log(Dog.prototype);
// constructor: ƒ Dog(name, breed) bark: ƒ bark()
console.log(dog1.__proto__);
// constructor: ƒ Dog(name, breed) bark: ƒ bark()构造函数的任何实例上的值,都是对构造函数原型的直接引用!每当我们尝试访问对象上不存在的属性时,JavaScript会沿着原型链向下查找,看该属性是否在原型链中可用。
__proto__当处理需要访问相同属性的对象时,原型模式非常强大。我们无需每次都重复创建属性,只需将属性添加到原型中,因为所有实例都可以访问原型对象。
由于所有实例都能访问原型,即使在创建实例后,我们也可以轻松地向原型添加属性。
比如我们的狗不仅要会吠叫,还要会玩耍!我们可以通过向原型添加属性来实现这一点。
play原型链这个术语意味着可能存在多个层级。确实如此!到目前为止,我们只看到了如何访问直接引用的第一个对象上的属性。但原型本身也有对象!
__proto____proto__让我们创建另一种狗——超级狗!这种狗应该继承普通的所有特性,还能飞行。我们可以通过扩展类并添加方法来创建超级狗。
DogDogflyjs
class SuperDog extends Dog {
constructor(name) {
super(name);
}
fly() {
return "Flying!";
}
}我们可以访问方法,因为我们扩展了类。原型上的值指向对象!
barkDogSuperDog__proto__Dog.prototype现在就明白为什么它被称为原型链了:当我们尝试访问对象上不存在的属性时,JavaScript会递归遍历指向的所有对象,直到找到该属性为止!
__proto__Object.create
Object.createObject.create
Object.createThe method lets us create a new object, to which we can explicitly pass the value of its prototype.
Object.createjs
const dog = {
bark() {
return `Woof!`;
},
};
const pet1 = Object.create(dog);Although itself doesn't have any properties, it does have access to properties on its prototype chain! Since we passed the object as 's prototype, we can access the property.
pet1dogpet1barkObject.createThe prototype pattern allows us to easily let objects access and inherit properties from other objects. Since the prototype chain allows us to access properties that aren't directly defined on the object itself, we can avoid duplication of methods and properties, thus reducing the amount of memory used.
Object.createjs
const dog = {
bark() {
return `Woof!`;
},
};
const pet1 = Object.create(dog);虽然本身没有任何属性,但它可以访问原型链上的属性!由于我们将对象作为的原型传入,因此可以访问属性。
pet1dogpet1barkObject.create原型模式让我们能够轻松地让对象访问和继承其他对象的属性。由于原型链允许我们访问未直接定义在对象本身的属性,因此我们可以避免方法和属性的重复,从而减少内存占用。