【Web 前端】JS继承的方法有哪些?

简介: 【4月更文挑战第22天】【Web 前端】JS继承的方法有哪些?

image.png

在 JavaScript 中,实现继承的方法有多种,每种方法都有其优缺点,适用于不同的场景。常见的继承方法包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承等。本文将对这些继承方法进行详细分析,并提供示例代码片段帮助读者理解各种继承方法的特点和用法。

1. 原型链继承

原型链继承是 JavaScript 中最基本的继承方式之一,它通过将子类的原型对象设置为父类的实例来实现继承。这样子类就可以访问父类的属性和方法,同时也可以添加自己的属性和方法。

优点:

  • 简单易懂,容易实现。

缺点:

  • 所有子类实例共享同一个原型对象,可能会导致属性被共享、引用类型值被修改的问题。
  • 无法向父类构造函数传递参数。

示例代码:

// 父类
function Animal(name) {
   
   
    this.name = name;
}
Animal.prototype.sayName = function() {
   
   
    console.log('My name is ' + this.name);
};

// 子类
function Dog() {
   
   }
Dog.prototype = new Animal(); // 将 Dog 的原型对象设置为 Animal 的实例

let dog = new Dog('Buddy');
dog.sayName(); // 输出 "My name is Buddy"

2. 构造函数继承(借用构造函数)

构造函数继承是通过在子类构造函数中调用父类构造函数来实现继承的方式。这样可以实现父类构造函数中的属性和方法被子类继承,但无法继承父类原型对象上的方法。

优点:

  • 可以向父类构造函数传递参数。
  • 避免了子类实例共享父类原型对象带来的问题。

缺点:

  • 无法继承父类原型对象上的方法,每个子类实例都会有自己的一份父类属性的副本。

示例代码:

// 父类
function Animal(name) {
   
   
    this.name = name;
}

// 子类
function Dog(name) {
   
   
    Animal.call(this, name); // 借用父类构造函数
}

let dog = new Dog('Buddy');
console.log(dog.name); // 输出 "Buddy"

3. 组合继承

组合继承是将原型链继承和构造函数继承结合起来使用的一种继承方式。通过将子类的原型对象设置为父类的实例,并在子类构造函数中调用父类构造函数,实现同时继承父类原型对象上的方法和父类构造函数中的属性。

优点:

  • 结合了原型链继承和构造函数继承的优点,解决了它们各自的缺点。

缺点:

  • 调用了两次父类构造函数,造成了一些不必要的性能消耗。

示例代码:

// 父类
function Animal(name) {
   
   
    this.name = name;
}
Animal.prototype.sayName = function() {
   
   
    console.log('My name is ' + this.name);
};

// 子类
function Dog(name, breed) {
   
   
    Animal.call(this, name); // 借用父类构造函数
    this.breed = breed;
}
Dog.prototype = new Animal(); // 将子类的原型对象设置为父类的实例
Dog.prototype.constructor = Dog; // 修正子类的 constructor

let dog = new Dog('Buddy', 'Labrador');
dog.sayName(); // 输出 "My name is Buddy"
console.log(dog.breed); // 输出 "Labrador"

4. 原型式继承

原型式继承是通过复制一个对象来实现继承的方式,类似于复制一个对象的原型对象。这种继承方式适用于创建简单对象,并且不需要单独创建构造函数的场景。

优点:

  • 简单方便,适用于创建简单对象。

缺点:

  • 所有实例共享同一个原型对象,可能会导致属性被共享、引用类型值被修改的问题。
  • 无法向父类构造函数传递参数。

示例代码:

let animal = {
   
   
    type: 'Animal',
    sayType: function() {
   
   
        console.log('I am an ' + this.type);
    }
};

let dog = Object.create(animal); // 继承 animal 对象
dog.type = 'Dog';
dog.sayType(); // 输出 "I am an Dog"

5. 寄生式继承

寄生式继承是在原型式继承的基础上增强,它在原型式继承的基础上,对返回的对象进行了增强,然后返回这个对象。

优点:

  • 可以在原型式继承的基础上增强对象的功能。

缺点:

  • 与原型式继承一样,所有实例共享同一个原型对象,可能会导致属性被共享、引用类型值被修改的问题。

示例代码:

function createDog(obj) {
   
   
    let dog = Object.create(obj); // 继承 obj 对象
    dog.bark = function() {
   
   
        console.log('Woof!');
    };
    return dog;
}

let animal = {
   
   
    type

: 'Animal',
    sayType: function() {
   
   
        console.log('I am an ' + this.type);
    }
};

let dog = createDog(animal); // 增强对象功能
dog.type = 'Dog';
dog.sayType(); // 输出 "I am an Dog"
dog.bark(); // 输出 "Woof!"

6. 寄生组合式继承

寄生组合式继承是对组合继承的一种优化,通过借用构造函数继承父类属性,并通过原型链继承父类原型对象上的方法,实现了高效的继承方式。

优点:

  • 结合了构造函数继承和原型链继承的优点,避免了它们各自的缺点,是一种高效的继承方式。

缺点:

  • 需要调用两次父类构造函数,可能会造成一些不必要的性能消耗。

示例代码:

// 父类
function Animal(name) {
   
   
    this.name = name;
}
Animal.prototype.sayName = function() {
   
   
    console.log('My name is ' + this.name);
};

// 子类
function Dog(name, breed) {
   
   
    Animal.call(this, name); // 借用父类构造函数
    this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype); // 将子类的原型对象设置为父类的原型对象
Dog.prototype.constructor = Dog; // 修正子类的 constructor

let dog = new Dog('Buddy', 'Labrador');
dog.sayName(); // 输出 "My name is Buddy"
console.log(dog.breed); // 输出 "Labrador"

7. 总结

在 JavaScript 中,实现继承的方法有多种,每种方法都有其优缺点,适用于不同的场景。常见的继承方法包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承等。通过本文的详细分析和示例代码,读者应该能够更好地理解各种继承方法的特点和用法,从而在实际项目中选择合适的继承方式。

相关文章
|
6天前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
10天前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
13天前
|
前端开发 JavaScript 安全
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第27天】本文介绍了HTTP/2和HTTPS在前端性能调优中的应用。通过多路复用、服务器推送和头部压缩等特性,HTTP/2显著提升了Web性能。同时,HTTPS确保了数据传输的安全性。文章提供了示例代码,展示了如何使用Node.js创建一个HTTP/2服务器。
27 3
|
9天前
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
9天前
|
缓存 JavaScript UED
js中BOM中的方法
【10月更文挑战第31天】
|
9天前
|
JavaScript 前端开发
.js方法参数argument
【10月更文挑战第26天】`arguments` 对象为JavaScript函数提供了一种灵活处理参数的方式,能够满足各种不同的参数传递和处理需求,在实际开发中具有广泛的应用价值。
25 7
|
10天前
|
监控 前端开发 JavaScript
探索微前端架构:构建可扩展的现代Web应用
【10月更文挑战第29天】本文探讨了微前端架构的核心概念、优势及实施策略,通过将大型前端应用拆分为多个独立的微应用,提高开发效率、增强可维护性,并支持灵活的技术选型。实际案例包括Spotify和Zalando的成功应用。
|
8天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
8天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
13 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
9天前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。