JS 继承的七种姿势:纵横 JavaScript 继承之道
2023-12-05 22:58:02
- 原型链继承
原型链继承是 JavaScript 中最基本的继承方式。它是通过原型链来实现的。原型链是 JavaScript 中的一个概念,它了对象之间的继承关系。每个对象都有一个原型对象,原型对象又可能有自己的原型对象,如此往复,直到遇到 null。
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log(this.name);
};
function Student(name, grade) {
Person.call(this, name);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
const student = new Student("John", 10);
student.sayName(); // John
在上面的代码中,Student
函数通过 Person.call(this, name)
调用 Person
函数的构造函数来继承 Person
函数的属性和方法。然后,Student.prototype
被设置为 Object.create(Person.prototype)
,这使得 Student
函数的原型对象成为 Person
函数的原型对象的副本。这样,Student
函数的实例就可以访问 Person
函数的属性和方法。
2. 类继承
ES6 中引入了 class
,它允许您使用类的方式来定义对象。类继承是通过 extends
关键字来实现的。
class Person {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Student extends Person {
constructor(name, grade) {
super(name);
this.grade = grade;
}
}
const student = new Student("John", 10);
student.sayName(); // John
在上面的代码中,Student
类通过 extends Person
继承了 Person
类的属性和方法。然后,Student
类的构造函数通过 super(name)
调用 Person
类的构造函数来继承 Person
类的属性和方法。这样,Student
类的实例就可以访问 Person
类的属性和方法。
3. 组合继承
组合继承是原型链继承和类继承的结合。它通过 Object.create()
和 super()
关键字来实现。
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log(this.name);
};
function Student(name, grade) {
Person.call(this, name);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
const student = new Student("John", 10);
student.sayName(); // John
在上面的代码中,Student
函数通过 Person.call(this, name)
调用 Person
函数的构造函数来继承 Person
函数的属性和方法。然后,Student.prototype
被设置为 Object.create(Person.prototype)
,这使得 Student
函数的原型对象成为 Person
函数的原型对象的副本。最后,Student.prototype.constructor
被设置为 Student
,这使得 Student
函数的实例的 constructor
属性指向 Student
函数。这样,Student
函数的实例就可以访问 Person
函数的属性和方法。
4. 寄生组合继承
寄生组合继承是组合继承的改进。它通过创建一个新的对象来继承 Person
函数的属性和方法,然后再将这个新的对象作为 Student
函数的原型对象。
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log(this.name);
};
function Student(name, grade) {
const person = new Person(name);
person.grade = grade;
return person;
}
const student = new Student("John", 10);
student.sayName(); // John
在上面的代码中,Student
函数通过创建一个新的 Person
对象来继承 Person
函数的属性和方法。然后,Student
函数将这个新的对象作为自己的原型对象。这样,Student
函数的实例就可以访问 Person
函数的属性和方法。
5. ES6 class 继承
ES6 中引入了 class
关键字,它允许您使用类的方式来定义对象。ES6 的类继承是通过 extends
关键字来实现的。
class Person {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Student extends Person {
constructor(name, grade) {
super(name);
this.grade = grade;
}
}
const student = new Student("John", 10);
student.sayName(); // John
在上面的代码中,Student
类通过 extends Person
继承了 Person
类的属性和方法。然后,Student
类的构造函数通过 super(name)
调用 Person
类的构造函数来继承 Person
类的属性和方法。这样,Student
类的实例就可以访问 Person
类的属性和方法。
6. Mixin
Mixin 是一个 JavaScript 对象,它包含了一组可以被其他对象复用的方法。Mixin 可以通过 Object.assign()
方法来实现。
const mixin = {
sayName() {
console.log(this.name);
}
};
function Person(name) {
this.name = name;
}
Object.assign(Person.prototype, mixin);
const person = new Person("John");
person.sayName(); // John
在上面的代码中,mixin
对象包含了一个 sayName()
方法。Person
函数通过 Object.assign(Person.prototype, mixin)
将 mixin
对象的方法添加到 Person
函数的原型对象上。这样,Person
函数的实例就可以访问 mixin
对象的方法。
7. 多重继承
JavaScript 不支持多重继承,这意味着一个类只能继承一个父类。但是,您可以通过组合继承或寄生组合继承来实现多重继承。
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log(this.name);
};
function Animal(type) {
this.type = type;
}
Animal.prototype.sayType = function() {
console.log(this.type);
};
function Student(name, grade) {
Person.call(this, name);
Animal.call(this, "Student");
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
const student = new Student("John", 10);
student.sayName(); // John
student.sayType(); // Student
在上面的代码中,Student
函数通过组合继承继承了 Person
函数和 Animal
函数的属性和方法。这样,Student
函数的实例就可以访问 Person
函数和 Animal
函数的属性和方法。
总结
本文介绍了 JavaScript 中的七种继承方式。每种继承方式都有其优缺点,您可以根据自己的需求选择最合适的继承方式。