Javascript 简明教程
JavaScript - Mixins
Mixins in JavaScript
JavaScript 中的混合允许将其他对象或类的属性添加到目标对象或类的原型中,并扩展目标对象的functionality。之后,可以使用目标对象访问其他对象的method。
The mixins in JavaScript allow you to add the properties of the other objects or classes to the target object’s or class’s prototype and extend the functionality of the target object. After that, you can access the other object’s method using the target object.
在 JavaScript 中,每个对象都包含一个称为 prototypeof 内置属性。原型本身就是一个对象。因此,原型对象将拥有其自己的原型属性,从而形成我们所说的原型更改。原型链有助于从其他对象继承属性和方法。
In JavaScript, each object contains a built-in property called prototype. The prototype is itself an object. So prototype object will have its own prototype property making what we call prototype changing. Prototype chain helps to inherit properties and methods from other objects.
此外,可以说混合允许从其他对象或类借用functionality。
Also, you can say that mixins allow you to borrow functionality from other objects or classes.
在 JavaScript 中,继承允许你扩展对象或类的功能。同样,混入也可以让你扩展对象或类的功能。
In JavaScript, inheritance allows you to extend the functionality of the object or class. Similarly, Mixins also allows you to extend the functionality of the object or classes.
JavaScript Mixins with Objects
使用 JavaScript 混入的概念,可以通过添加其他对象的属性和方法来扩展目标对象的功能。
Using the concept of the JavaScript mixins, you can extend the functionality of the target object by adding properties and methods of the other objects.
Syntax
下列是使用 JavaScript 混入与对象一起的语法:
Following is the syntax to use Mixins with objects in JavaScript −
Object.assign(target, obj);
在上面的语法中,我们使用 Object.assign()
方法来扩展目标对象的功能。
In the above syntax, we used the Object.assign() method to extend the functionality of the target object.
Parameters
-
target − It is an object whose functionality you need to extend.
-
obj − It is an object whose functionality will be extended by the target object.
Example
在下面的代码中,父对象包含 printMessage()
函数,子对象包含 showName()
方法。这两个方法打印不同的消息。
In the below code, the parent object contains the printMessage(), and the child object contains the showName() method. Both methods print different messages.
然后,我们使用 Object.assign()
方法来扩展子对象使用父对象方法的功能。
After that, we used the Object.assign() method to extend the functionality of the child object with the methods of the parent object.
接下来,我们只使用子对象调用父对象和子对象的不同消息,然后你可以看到输出结果。
Next, we invoke the parent and child object message using the child object only, and you can observe the output.
<html>
<body>
<p id = "output"> </p>
<script>
const output = document.getElementById("output");
const parent = {
name: "parent",
printMessage() {
output.innerHTML = 'This is a parent object.<br>';
}
}
const child = {
showName() {
output.innerHTML += 'This is a child object.<br>';
}
}
Object.assign(child, parent); // Mixins
child.printMessage(); //Executing the method of parent object using child object
child.showName();
</script>
</body>
</html>
This is a parent object.
This is a child object.
JavaScript Mixins with Classes
你也可以使用混入通过对象来扩展类别的功能。
You can also extend the functionality of the classes through objects using the mixins.
Syntax
我们可以遵循下面的语法来使用类的混入部分:
We can follow the syntax below to use mixins with classes −
Object.assign(class_name.prototype, obj);
上面的语法中,我们把类的原型作为第一个参数,对象作为第二个参数,然后它们的函数需要扩展类。
In the above syntax, we have passed the prototype of the class as the first parameter and the object as a second parameter whose functionalities need to extend with classes.
Example
下面的代码中,animal
对象包含 eats
属性和 run()
方法。cat
类只包含构造函数。
In the below code, the animal object contains the 'eats' property and run() method. The cat class contains only the constructor.
我们添加 animal
对象的方法和属性添加到 cat
类的原型。然后,我们使用 cat
类的实例执行 run()
方法。
We add the methods and properties of the animal object to the cat class’s prototype. After that, we execute the run() method using the instance of the cat class.
<html>
<body>
<p id = "output"> </p>
<script>
const output = document.getElementById("output");
const animal = {
eats: true,
run() {
output.innerHTML += "Animals run. <br>";
}
}
class cat {
constructor() {
this.name = "Cat";
}
}
Object.assign(cat.prototype, animal); // Mixins
const catObj = new cat();
output.innerHTML += "Cat eats: " + catObj.eats + "<br>";
catObj.run();
</script>
</body>
</html>
Cat eats: true
Animals run.
Achieving Multiple Inheritance Using the Mixins
JavaScript 不支持多重继承,这意味着扩展一个类的功能使用多个类或对象。但是,你可以使用混入来实现多重继承。
JavaScript doesn’t support multiple inheritance, which means extending one class’s functionality with multiple classes or objects. So, you can achieve multiple inheritance using mixins.
Syntax
用户可以遵循下面的语法来使用混入实现多重继承:
Users can follow the syntax below to use the mixins to achieve multiple inheritance.
Object.assign(target, ob1, obj);
上面的语法将添加 obj1
和 obj2
对象的功能添加到目标对象。
The above syntax will add the obj1 and obj2 object’s functionality to the target object.
Example: Inheriting multiple objects
在下面的代码中,eat
对象包含 eatFood()
方法,而 drink
对象包含 drinkWater()
方法。
In the below code, eat object contains the eatFood() method, and the drink object contains the drinkWater() method.
我们添加 eat
和 drink
对象的属性和方法到 person
对象。然后,我们使用 person
对象访问 eatFood()
和 drinkWater()
方法。
We add properties and methods of the eat and drink object to the person object. After that, we access the eatFood() and drinkWater() methods using the person object.
<html>
<body>
<div id = "demo"> </div>
<script>
const output = document.getElementById("demo");
const eat = {
eatFood() {
output.innerHTML += "Person is eating the food! <br>";
}
}
const drink = {
drinkWater() {
output.innerHTML += "Person is drinking water! <br>";
}
}
const person = {
name: "John",
}
Object.assign(person, eat, drink); // Mutiple Mixins
person.eatFood();
person.drinkWater();
</script>
</body>
</html>
Person is eating the food!
Person is drinking water!
Example: Multiple Inheritance with Classes
以下实例演示了使用多个类来扩展一个类。
The below example demonstrates extending one class with multiple classes.
Entity 类是父类,它包含 state() 方法。Human 类扩展了 Entity 类并包含 walk() 方法。
The Entity class is the parent class, and it contains the state() method. The Human class extends the Entity class and contains the walk() method.
Driver() 函数创建了一个新类,扩展了作为参数传递的类并在类中添加了 Drive() 方法。类似地,Swimmer() 函数创建了一个新类,扩展了用作参数传递的类的类并在类中添加了 swim() 方法。
The Driver() function creates a new class, extends a class passed as a parameter, and adds the Drive() method to the class. Similarly, the Swimmer() function creates a new class, extends the class with a class passed as a parameter, and adds the swim() method.
然后,我们定义了其他几个类。person 类扩展了 Driver() 类返回的类。Driver() 函数返回了一个用 Human 类扩展的新类。同样,我们创建了 Mechanic 和 SwimmerPerson 类。
After that, we defined multiple other classes. The person class extends the class returned by the Driver() class. The Driver() function returns a new class extended with the Human class. Same way, we have created the Mechanic and SwimmerPerson classes.
在完成此操作之后,我们创建了各种类的对象并执行了它们继承的方法。
After that, we have created the objects of various classes and executed the methods inherited by them.
<html>
<body>
<p id = "demo"> </p>
<script>
let output = document.getElementById("demo");
// Parent class
class Entity {
state() {
return 'It is in the idle state!';
}
}
// Child class
class Human extends Entity {
walk() {
return 'walking on the field.';
}
}
// Custom functionalities
function Driver(parentClass) {
return class extends parentClass {
drive() {
return 'driving on the road';
}
};
}
function Swimmer(parentClass) {
return class extends parentClass {
swim() {
return 'swimming in water';
}
};
}
// Some other classes
class Person extends Driver(Human) { }
class Mechanic extends Driver(Entity) { }
class SwimmerPerson extends Swimmer(Person) { }
// Objects of classes
const person = new Person();
const personDrive = person.drive();
const mechanic = new Mechanic();
const mechanicDrive = mechanic.drive();
const swimmerPerson = new SwimmerPerson();
const swimmerDrive = swimmerPerson.drive();
const swimmerSwim = swimmerPerson.swim();
// Printing outputs
output.innerHTML += 'State of the PERSON: ' + personDrive + '<br>';
output.innerHTML += 'State of the MECHANIC: ' + mechanicDrive + '<br>';
output.innerHTML += 'State of the SWIMMER PERSON: ' + swimmerDrive + ", " + swimmerSwim + '<br>';
</script>
</body>
</html>
State of the PERSON: driving on the road
State of the MECHANIC: driving on the road
State of the SWIMMER PERSON: driving on the road, swimming in water
通过这种方式,你可以使用 mixin 来实现多重继承。
This way, you can use the mixins to achieve multiple inheritance.
Benefits of using Mixins
我们在此列出了一些使用 mixin 的好处。
Here, we have listed some benefits of using mixins.
-
Code reusability − You can reuse the code by borrowing methods and properties from other objects of other classes.
-
Multiple inheritance − JavaScript doesn’t support multiple inheritance by default, but you can achieve similar functionalities using mixins.
-
Extensibility − You can add additional functionalities to the classes or objects without changing the structure of the objects or classes using mixins.
Limitations of Mixins
我们在此列出了一些 mixin 的局限性以及一些开发人员避免使用 mixin 的原因。
Here, we have listed some limitations of mixins and reasons why some developers avoid using mixins.
-
Complexity − If you overuse the mixins, it increases the complexity of the code, which you can see in the last example of this tutorial.
-
Pseudo inheritance − The mixin can fulfill the requirements of the inheritance, but using the mixins, you can’t achieve true inheritance.
-
Naming collision − If you combine multiple objects, there is a high chance of naming collision.