构造函数和原型的结合应用:轻松搞定JS的面向对象编程(三)

简介: 构造函数和原型的结合应用:轻松搞定JS的面向对象编程

构造函数和原型的结合应用:轻松搞定JS的面向对象编程(二)https://developer.aliyun.com/article/1426302


通过例子说明继承的实现

下面通过一个简单的例子来说明如何实现继承:

// 定义一个基础的动物类
function Animal(name, age) {
  // 定义动物的名称和年龄
  this.name = name;
  this.age = age;
}
// 为 Animal 原型对象添加共享方法
Animal.prototype.sayHello = function() {
  console.log(`Hi, I am ${this.name}, I'm ${this.age} years old.`);
};
// 定义一个狗类,派生于动物类
function Dog(name, age, breed) {
  // 调用父类的构造函数,传入名称和年龄
  Animal.call(this, name, age);
  // 定义狗的品种
  this.breed = breed;
}
// 让 Dog 类继承 Animal 类的原型
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 定义 Dog 类自己的方法
Dog.prototype.bark = function() {
  console.log(`${this.name} barks.`);
};
// 创建 Dog 实例,调用父类方法和自身方法
const dog = new Dog('Little Black', 2, 'Golden Retriever');
dog.sayHello(); // Hi, I am Little Black, I'm 2 years old.
dog.bark(); // Little Black barks.

在这个例子中,我们定义了一个 Animal 类和一个 Dog 类,Dog 类派生于 Animal 类。在 Dog 类的构造函数中,我们调用了父类的构造函数 Animal.call(this, name, age),以获取来自父类的属性。同时,我们还将 Dog 类的原型对象指向 Animal 类的原型,以实现继承。在 Dog 类中,我们还定义了自己的方法 bark。

最后,我们创建了一个 Dog 实例,并调用了父类方法和自身方法,由此可以看到,Dog 实例成功地继承了 Animal 类的属性和方法,并增加了自己的方法。

VI. 面向对象与原型

介绍面向对象编程

面向对象编程(Object-oriented programming,OOP)是一种程序设计范式,它将程序中的各种功能模块(即对象)封装起来,以便于代码的复用和管理。在 OOP 中,对象是指具有特定行为、状态和标识的实体,它们封装了数据和任务,并通过相互通信来完成任务。

面向对象编程中的三个核心概念是:封装、继承和多态。封装是指将对象的状态和行为组合在一起,隐藏对象内部的细节,只向外界暴露必要的接口。继承是指一个对象可以从另一个对象继承其属性和方法,并在此基础上定制自己的行为。多态是指同一种行为可以用不同的方式实现,不同的对象可以对同一种消息作出不同的响应。

在面向对象编程中,每一个对象都有自己的属性和方法,属性是对象的状态,方法是对象的行为,它们共同组成了一个对象的整体。面向对象编程的思想是通过对一个对象进行操作来实现功能的,而不是通过操作过程来实现功能。

OOP 技术是一种非常强大的技术,它可以大幅提高代码的重用性、可扩展性和可维护性,因此在软件开发中被广泛应用。常用的 OOP 编程语言有 Java、C++、Python 等。

说明原型在面向对象中的作用

在面向对象编程中,原型是一个非常重要的概念,它是 JavaScript 中实现继承的关键。

JavaScript 中,每个对象都有一个原型对象,它是一个指向另一个对象的引用,这个被引用的对象就是该对象的原型。

原型对象存储了对象的属性和方法,它们是该对象的“原型”,即该对象继承的来源。在 JavaScript 中,通过原型链,我们可以实现对象之间的继承。当一个对象调用它的方法时,如果它自己没有这个方法,它会去查找它的原型对象,如果原型对象也没有这个方法,它就会去查找原型对象的原型对象,以此类推,直到找到该方法或原型链的末尾。

使用原型对象的好处是对象之间可以实现属性和方法的共享,避免了在多个对象之间重复定义相同的属性和方法,从而提高了代码的复用性和可维护性。而且,通过修改原型对象的属性和方法,可以达到对所有继承该原型对象的对象都做出相应的改变的效果,这种特性可以被用于对多个对象进行动态修改和更新。

下面是一个通过原型实现继承的例子:

// 定义一个基础的动物类
function Animal(name, age) {
  // 定义动物的名称和年龄
  this.name = name;
  this.age = age;
}
// 为 Animal 原型对象添加共享方法
Animal.prototype.sayHello = function() {
  console.log(`Hi, I am ${this.name}, I'm ${this.age} years old.`);
};
// 定义一个狗类,派生于动物类
function Dog(name, age, breed) {
  // 调用父类的构造函数,传入名称和年龄
  Animal.call(this, name, age);
  // 定义狗的品种
  this.breed = breed;
}
// 让 Dog 类继承 Animal 类的原型
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 定义 Dog 类自己的方法
Dog.prototype.bark = function() {
  console.log(`${this.name} barks.`);
};
// 创建 Dog 实例,调用父类方法和自身方法
const dog = new Dog('Little Black', 2, 'Golden Retriever');
dog.sayHello(); // Hi, I am Little Black, I'm 2 years old.
dog.bark(); // Little Black barks.

在这个例子中,Animal 类定义了一个 sayHello 方法,这个方法被 Animal 的原型对象继承。而 Dog 类通过 Object.create() 方法将自己的原型指向 Animal 的原型,这样,Dog 类的实例就可以继承 Animal 的原型(包括其 sayHello 方法),并实现自己的 bark 方法。

通过例子说明面向对象和原型的结合应用

下面通过一个例子来说明面向对象和原型的结合应用:

// 定义一个基础的动物类
function Animal(name, age) {
  // 定义动物的名称和年龄
  this.name = name;
  this.age = age;
}
// 为 Animal 原型对象添加共享方法
Animal.prototype.sayHello = function() {
  console.log(`Hi, I am ${this.name}, I'm ${this.age} years old.`);
};
// 定义一个狗类,派生于动物类
function Dog(name, age, breed) {
  // 调用父类的构造函数,传入名称和年龄
  Animal.call(this, name, age);
  // 定义狗的品种
  this.breed = breed;
}
// 让 Dog 类继承 Animal 类的原型
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 为 Dog 原型对象添加共享方法
Dog.prototype.bark = function() {
  console.log(`${this.name} barks.`);
};
// 创建 Dog 实例,调用父类方法和自身方法
const dog1 = new Dog('Little Black', 2, 'Golden Retriever');
dog1.sayHello(); // Hi, I am Little Black, I'm 2 years old.
dog1.bark();     // Little Black barks.
// 创建另一个 Dog 实例
const dog2 = new Dog('Little White', 3, 'Husky');
dog2.sayHello(); // Hi, I am Little White, I'm 3 years old.
dog2.bark();     // Little White barks.

在这个例子中,我们定义一个 Animal 类和一个 Dog 类,Dog 类派生于 Animal 类。在 Animal 类的原型对象中,我们添加了一个 sayHello 方法,在 Dog 类的原型对象中,我们添加了一个 bark 方法。这两个方法都是在原型对象中定义的,因此它们可以被所有继承该原型对象的对象共享(即所有的 Dog 实例均包含了这两个方法)。

当我们创建 Dog 类的实例时,这些实例会自动继承他们的原型对象,因此,这些实例将包含原型对象中定义的所有方法和属性(例如 sayHellobark 方法)。我们在例子中创建了两个 Dog 实例,分别称为 dog1dog2, 它们都拥有 Animal 的 sayHello 方法和 Dog 的 bark 方法。

通过这种方式,我们可以将对象的属性和方法进行有效的管理,避免代码冗余和重复性代码的编写,同时提高代码的可读性和可维护性。

VII. 总结

对原型和原型链的应用做一个总结

总的来说,原型和原型链是在 JavaScript 中实现面向对象编程的基础。

  • 原型是一种机制,它通过在对象中存储属性和方法,实现代码的重用。在 JavaScript 中,每个对象都会有一个原型对象,如果某个对象的属性或方法找不到,就会去它的原型对象中去查找。因此,通过利用原型,不同的对象可以共享相同的属性和方法。
  • 原型链是一种继承机制,它通过将一个对象的原型设置为另一个对象,实现从父类(原型对象)到子类(继承对象)的层层继承。原型链是基于原型的继承,它可以直接使用原型对象上的方法和属性,并且可以通过继承,修改方法和属性,以实现自己的需求。

同时,原型和原型链的应用可以帮助我们有效地管理程序中大量的对象,减少代码重复,并提高代码的可读性和可维护性。以下是原型和原型链的一些具体应用:

  • 使用原型实现继承,可以避免代码重复和提高代码的可维护性。
  • 使用原型的共享属性和方法,可以在代码中实现更高的代码重用性和更好的性能。
  • 使用原型链的方式,可以快速地继承父类的方法和属性,同时在子类上增加新的方法和属性。
  • 通过修改原型对象上的属性和方法,可以实现对多个对象进行动态修改和更新。

总之,原型和原型链是 JavaScript 中的重要概念,能帮助我们更好地实现面向对象编程,同时提高代码的可维护性和可读性。在实际开发过程中,我们需要结合具体场景和需求,灵活使用原型和原型链机制,以实现更高效、简洁的代码。

相关文章
|
1月前
|
JavaScript 前端开发 算法
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
移动开发 运维 供应链
通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
array.some()可以用来权限检查、表单验证、库存管理、内容审查和数据处理等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
供应链 JavaScript 前端开发
通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
array.every()可以用来数据验证、权限检查、一致性检查等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
JavaScript 前端开发 Java
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
柯里化是一种强大的函数式编程技术,它通过将函数分解为单参数形式,实现了灵活性与可复用性的统一。无论是参数复用、延迟执行,还是函数组合,柯里化都为现代编程提供了极大的便利。 从 Redux 的选择器优化到复杂的数据流处理,再到深度嵌套的函数优化,柯里化在实际开发中展现出了非凡的价值。如果你希望编写更简洁、更优雅的代码,柯里化无疑是一个值得深入学习和实践的工具。从简单的实现到复杂的应用,希望这篇博客能为你揭开柯里化的奥秘,助力你的开发之旅! 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
1月前
|
数据采集 JavaScript 前端开发
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
用array.filter()来实现数据筛选、数据清洗和链式调用,相对于for循环更加清晰,语义化强,能显著提升代码的可读性和可维护性。博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
3月前
|
缓存 NoSQL JavaScript
Vue.js应用结合Redis数据库:实践与优化
将Vue.js应用与Redis结合,可以实现高效的数据管理和快速响应的用户体验。通过合理的实践步骤和优化策略,可以充分发挥两者的优势,提高应用的性能和可靠性。希望本文能为您在实际开发中提供有价值的参考。
84 11
|
3月前
|
敏捷开发 人工智能 JavaScript
Figma-Low-Code:快速将Figma设计转换为Vue.js应用,支持低代码渲染、数据绑定
Figma-Low-Code 是一个开源项目,能够直接将 Figma 设计转换为 Vue.js 应用程序,减少设计师与开发者之间的交接时间,支持低代码渲染和数据绑定。
210 3
Figma-Low-Code:快速将Figma设计转换为Vue.js应用,支持低代码渲染、数据绑定
|
3月前
|
JavaScript 前端开发
【Vue.js】监听器功能(EventListener)的实际应用【合集】
而此次问题的核心就在于,Vue实例化的时机过早,在其所依赖的DOM结构尚未完整构建完成时就已启动挂载流程,从而导致无法找到对应的DOM元素,最终致使计算器功能出现异常,输出框错误地显示“{{current}}”,并且按钮的交互功能也完全丧失响应。为了让代码结构更为清晰,便于后续的维护与管理工作,我打算把HTML文件中标签内的JavaScript代码迁移到外部的JS文件里,随后在HTML文件中对其进行引用。
69 8
|
3月前
|
监控 安全 中间件
Next.js 实战 (十):中间件的魅力,打造更快更安全的应用
这篇文章介绍了什么是Next.js中的中间件以及其应用场景。中间件可以用于处理每个传入请求,比如实现日志记录、身份验证、重定向、CORS配置等功能。文章还提供了一个身份验证中间件的示例代码,以及如何使用限流中间件来限制同一IP地址的请求次数。中间件相当于一个构建模块,能够简化HTTP请求的预处理和后处理,提高代码的可维护性,有助于创建快速、安全和用户友好的Web体验。