彻底理解JavaScript面向对象之继承
什么是继承?
在面向对象的编程中,继承是允许一个对象获取另一个对象的属性和方法的过程。可以把继承看做是在已有的类的基础上创建一个新类的过程。
在JavaScript中,继承是通过原型链实现的。每个对象都有一个原型对象,原型对象也可能有一个原型对象,以此类推,直到原型链的顶端为止。当试图访问一个对象的属性或方法时,会先在该对象本身中查找,如果没有找到,就会沿着原型链向上查找,直到找到该属性或方法为止。
继承的实现
在JavaScript中,可以使用以下几种方式来实现对象的继承:
1. 原型链继承
原型链继承是JavaScript中最常用的继承方式之一,通过将父类的实例赋值给子类的原型对象,子类就能够访问父类的属性和方法,从而实现了继承。
示例代码如下:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}, I'm ${this.age} years old.`);
}
function Student(name, age, grade) {
this.grade = grade;
}
// 继承 Person
Student.prototype = new Person();
// 将 constructor 指回 Student
Student.prototype.constructor = Student;
const student = new Student('Tom', 18, 'Grade1');
console.log(student.name); // Tom
console.log(student.age); // 18
console.log(student.grade); // Grade1
student.sayHello(); // Hello, my name is Tom, I'm 18 years old.
2. 构造函数继承
构造函数继承是通过在子类的构造函数中调用父类的构造函数来实现继承。通过使用call或apply方法,给父类传递子类的this对象,使得父类的属性和方法都能够在子类中使用。
示例代码如下:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}, I'm ${this.age} years old.`);
}
function Student(name, age, grade) {
// 调用 Person
Person.call(this, name, age);
this.grade = grade;
}
const student = new Student('Tom', 18, 'Grade1');
console.log(student.name); // Tom
console.log(student.age); // 18
console.log(student.grade); // Grade1
student.sayHello(); // TypeError: student.sayHello is not a function
由于构造函数继承只能继承父类的属性,无法继承父类的原型方法,所以在使用构造函数继承时,父类的方法不能通过prototype定义,需要在构造函数中定义。
3. 组合继承
组合继承是同时使用原型链继承和构造函数继承的方式,在构造函数中调用父类构造函数传递this对象,并将父类原型对象赋值给子类的原型对象。
示例代码如下:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}, I'm ${this.age} years old.`);
}
function Student(name, age, grade) {
// 调用 Person
Person.call(this, name, age);
this.grade = grade;
}
// 继承 Person 的原型方法
Student.prototype = new Person();
// 将 constructor 指回 Student
Student.prototype.constructor = Student;
const student = new Student('Tom', 18, 'Grade1');
console.log(student.name); // Tom
console.log(student.age); // 18
console.log(student.grade); // Grade1
student.sayHello(); // Hello, my name is Tom, I'm 18 years old.
总结
以上就是JavaScript中实现继承的几种方式,不同的继承方式具有不同的优劣性,可以根据实际场景来选择适合的方式。
继承是面向对象编程中非常重要的概念,对于JavaScript开发者来说,更要深入理解和应用继承,才能更好地进行代码设计和重用。
示例
下面给出一个使用原型链继承的示例:
function Animal(name, type) {
this.name = name;
this.type = type;
}
Animal.prototype.sayHello = function() {
console.log(`I'm a ${this.type}, my name is ${this.name}`);
}
function Cat(name) {
this.name = name;
}
// 继承自 Animal
Cat.prototype = new Animal();
// 将 constructor 指回 Cat
Cat.prototype.constructor = Cat;
// 自定义方法
Cat.prototype.scratch = function() {
console.log(`${this.name} is scratching.`);
}
const cat = new Cat('Tom');
cat.sayHello(); // I'm a undefined, my name is Tom
cat.scratch(); // Tom is scratching.
在上面的示例中,Cat继承自Animal,原型链上能够访问到Animal的方法sayHello,同时Cat还定义了一个自己的方法scratch。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:彻底理解js面向对象之继承 - Python技术站