前端JavaScript篇之对象创建的方式有哪些?

目录

  • 对象创建的方式有哪些?
    • 1. 工厂模式:
    • 2. 构造函数模式:
    • 3. 原型模式:
    • 4. 混合模式:
    • 5. 动态原型模式:
    • 6. 寄生构造函数模式:
    • 7. 字面量方式:


对象创建的方式有哪些?

JavaScript中创建对象的方式有多种,其中常用的有工厂模式、构造函数模式、原型模式、混合模式、动态原型模式和寄生构造函数模式。

1. 工厂模式:

使用一个函数封装创建对象的细节,通过调用函数来创建对象。但是对象无法和某个类型联系起来,缺乏类型识别。

function createPerson(name, age) {let person = {} // 创建一个空对象person.name = name // 给对象添加属性person.age = ageperson.sayHello = function () {// 给对象添加方法console.log("Hello, I'm " + this.name + '!')}return person // 返回对象
}let person1 = createPerson('张三', 18) // 创建对象
let person2 = createPerson('李四', 20)person1.sayHello() // 调用对象的方法
person2.sayHello()

请添加图片描述

在这个例子中,我们定义了一个 createPerson 函数,它接受两个参数 nameage。在函数内部,我们创建了一个空对象 person,并给它添加了两个属性 nameage,以及一个方法 sayHello。最后,我们返回这个对象。通过调用 createPerson 函数,我们可以创建多个对象,每个对象都有自己的 nameagesayHello 方法。

工厂模式的优点在于可以很好地封装对象的创建过程,从而提高代码的可维护性和可读性。但是,工厂模式无法识别对象的类型,因此无法使用 instanceof 运算符来判断对象的类型。另外,如果要添加新的方法或属性,需要修改工厂函数的代码,这可能会导致代码的不稳定性。

2. 构造函数模式:

使用构造函数模式创建对象,定义一个函数,通过 new 关键字调用函数,将 this 指向新建的对象,从而达到复用的目的。这种方式可以识别对象的类型。

function Person(name, age) {this.name = namethis.age = agethis.sayHello = function () {console.log("Hello, I'm " + this.name + '!')}
}let person1 = new Person('张三', 18) // 创建对象
let person2 = new Person('李四', 20)person1.sayHello() // 调用对象的方法
person2.sayHello()

请添加图片描述

在这个例子中,我们定义了一个 Person 构造函数,它接受两个参数 nameage。在函数内部,我们使用 this 关键字给对象添加了两个属性 nameage,以及一个方法 sayHello。使用 new 关键字调用构造函数时,会创建一个新的对象,并将 this 关键字指向这个新对象。最后,构造函数会返回这个新对象。通过调用 Person 构造函数,我们可以创建多个对象,每个对象都有自己的 nameagesayHello 方法。

构造函数模式的优点在于可以识别对象的类型,因此可以使用 instanceof 运算符来判断对象的类型。另外,如果要添加新的方法或属性,只需要在构造函数内部添加即可,这样更加灵活。但是,由于每个对象都会创建自己的方法,因此会占用更多的内存空间。

3. 原型模式:

使用原型对象来添加公用属性和方法,实现代码复用。每个函数都有一个 prototype 属性,使用原型模式创建对象,定义一个构造函数,将对象的属性和方法添加到构造函数的原型对象上。这种方式可以实现属性和方法的共享,从而节省内存空间。

function Person(name, age) {this.name = namethis.age = age
}Person.prototype.sayHello = function () {console.log("Hello, I'm " + this.name + '!')
}let person1 = new Person('张三', 18) // 创建对象
let person2 = new Person('李四', 20)person1.sayHello() // 调用对象的方法
person2.sayHello()

请添加图片描述

在这个例子中,我们定义了一个 Person 构造函数,它接受两个参数 nameage。在函数内部,我们使用 this 关键字给对象添加了两个属性 nameage。然后,我们将 sayHello 方法添加到构造函数的原型对象上。使用 new 关键字调用构造函数时,会创建一个新的对象,并将 this 关键字指向这个新对象。最后,构造函数会返回这个新对象。通过调用 Person 构造函数,我们可以创建多个对象,每个对象都有自己的 nameage 属性,以及共享的 sayHello 方法。

原型模式的优点在于可以实现属性和方法的共享,从而节省内存空间。由于每个对象共享同一个原型对象上的方法,因此不会占用额外的内存空间。另外,如果要添加新的方法或属性,只需要在原型对象上添加即可,这样更加灵活。但是,由于所有对象共享同一个原型对象,因此如果一个对象修改了原型对象上的属性或方法,会影响到其他对象。

4. 混合模式:

组合使用构造函数模式和原型模式,通过构造函数来初始化对象的属性,通过原型对象来实现函数方法的复用。结合构造函数模式和原型模式的优点,既可以识别对象的类型,又可以实现属性和方法的共享。

function Person(name, age) {this.name = namethis.age = age
}Person.prototype.sayHello = function () {console.log("Hello, I'm " + this.name + '!')
}let person1 = new Person('张三', 18) // 创建对象
let person2 = new Person('李四', 20)person1.sayHello() // 调用对象的方法
person2.sayHello()function Student(name, age, grade) {Person.call(this, name, age) // 继承属性this.grade = grade
}Student.prototype = Object.create(Person.prototype) // 继承方法
Student.prototype.constructor = Student // 修复 constructorStudent.prototype.study = function () {console.log(this.name + ' is studying in grade ' + this.grade + '.')
}let student1 = new Student('王五', 16, 10) // 创建对象
let student2 = new Student('赵六', 17, 11)student1.sayHello() // 调用继承自 Person 的方法
student1.study() // 调用自己的方法
student2.sayHello()
student2.study()

请添加图片描述

在这个例子中,我们定义了一个 Person 构造函数,它接受两个参数 nameage。在函数内部,我们使用 this 关键字给对象添加了两个属性 nameage。然后,我们将 sayHello 方法添加到构造函数的原型对象上。使用 new 关键字调用构造函数时,会创建一个新的对象,并将 this 关键字指向这个新对象。最后,构造函数会返回这个新对象。通过调用 Person 构造函数,我们可以创建多个对象,每个对象都有自己的 nameage 属性,以及共享的 sayHello 方法。

接着,我们定义了一个 Student 构造函数,它继承自 Person 构造函数。使用 call 方法调用 Person 构造函数,将 this 关键字指向新建的 Student 对象,并传入 nameage 参数,从而继承了 Person 构造函数的属性。然后,我们将 Student 构造函数的原型对象指向一个新的 Person 构造函数的原型对象,从而继承了 Person 构造函数的方法。最后,我们添加了一个 study 方法,用于 Student 对象自己的行为。

使用 new 关键字调用 Student 构造函数时,会创建一个新的对象,并将 this 关键字指向这个新对象。最后,构造函数会返回这个新对象。通过调用 Student 构造函数,我们可以创建多个对象,每个对象都有自己的 nameagegrade 属性,以及继承自 Person 构造函数的 sayHello 方法和自己的 study 方法。

混合模式的优点在于既可以识别对象的类型,又可以实现属性和方法的共享。通过继承构造函数模式的属性和原型模式的方法,可以更加灵活地创建对象。但是,由于需要继承两个部分的内容,因此代码量较多。

5. 动态原型模式:

动态原型模式是一种设计模式,用于在JavaScript中创建对象。它的主要思路是在构造函数内部判断是否需要初始化原型,如果需要,则在构造函数内部定义原型方法。将原型方法赋值的创建过程移动到构造函数的内部,通过对属性是否存在的判断,实现仅在第一次调用函数时对原型对象赋值一次的效果。

function Person(name, age) {this.name = namethis.age = age// 判断是否需要初始化原型if (typeof this.sayHello !== 'function') {// 定义原型方法Person.prototype.sayHello = function () {console.log('Hello, my name is ' + this.name + ' and I am ' + this.age + ' years old.')}}
}// 创建两个Person对象
var person1 = new Person('Alice', 25)
var person2 = new Person('Bob', 30)// 调用原型方法
person1.sayHello() // 输出: Hello, my name is Alice and I am 25 years old.
person2.sayHello() // 输出: Hello, my name is Bob and I am 30 years old.

请添加图片描述

在上述代码中,我们定义了一个Person构造函数,它接受nameage作为参数,并将它们赋值给实例变量。然后,我们使用动态原型模式来检查是否需要初始化原型方法sayHello。如果原型中不存在sayHello方法,那么我们就在构造函数内部定义该方法。

这样做的好处是,每次创建新的Person对象时,不会重复地定义原型方法。只有在第一次创建对象时,才会初始化原型方法。这样可以节省内存,并且避免了每个实例都拥有相同的原型方法的副本。

通过使用动态原型模式,我们可以灵活地定义构造函数和原型方法,并确保它们在需要的时候被正确地初始化。

6. 寄生构造函数模式:

寄生构造函数模式是一种设计模式,它通过在一个普通的构造函数内部创建并返回一个新对象,从而实现对构造函数的扩展。这个新对象通常被称为"寄生对象"。

function Person(name, age) {var obj = {} // 创建一个空对象// 对空对象进行属性和方法的添加obj.name = nameobj.age = ageobj.sayHello = function () {console.log('Hello, my name is ' + this.name + ' and I am ' + this.age + ' years old.')}return obj // 返回新创建的对象
}// 创建一个Person对象
var person = new Person('Alice', 25)// 调用对象的方法
person.sayHello() // 输出: Hello, my name is Alice and I am 25 years old.

请添加图片描述

在上述代码中,我们定义了一个Person构造函数,它接受nameage作为参数。在构造函数内部,我们创建了一个空对象obj,并向其添加了nameage属性以及sayHello方法。

最后,我们将新创建的对象obj返回,作为构造函数的结果。这样,在调用new Person()时,会得到一个包含了指定属性和方法的新对象。

使用寄生构造函数模式可以在不改变原始构造函数的情况下,对其进行扩展。这种模式常用于需要在原始构造函数的基础上添加额外功能或修改返回对象的情况下。然而,需要注意的是,寄生构造函数模式会导致每个新对象都拥有自己的方法副本,可能会造成内存浪费。因此,在使用该模式时要谨慎考虑其适用性和性能影响。

7. 字面量方式:

字面量方式是一种直接使用花括号{}来定义对象的方式。

// 创建一个对象并定义属性和方法
var person = {name: 'Alice',age: 25,sayHello: function () {console.log('Hello, my name is ' + this.name + ' and I am ' + this.age + ' years old.')}
}// 访问对象的属性和调用方法
console.log(person.name) // 输出: Alice
console.log(person.age) // 输出: 25
person.sayHello() // 输出: Hello, my name is Alice and I am 25 years old.![请添加图片描述](https://img-blog.csdnimg.cn/direct/89a64e636e56468bb8d122c13b5c64d7.png)

在上述代码中,我们使用字面量方式创建了一个名为person的对象。通过花括号{},我们直接在对象内部定义了属性nameage,以及方法sayHello

然后,我们可以通过点号.来访问对象的属性,例如person.nameperson.age。同时,我们也可以使用person.sayHello()来调用对象的方法。

字面量方式创建对象简单明了,适合创建单个对象或者只需要临时使用的对象。它不需要使用构造函数或原型,并且可以直接在对象内部定义属性和方法,非常方便。然而,由于每次创建对象都需要重新定义属性和方法,所以不适合创建大量相似的对象,这种情况下可以考虑使用其他方式,如构造函数或工厂模式。

总结:JavaScript中创建对象的方式有多种,每种方式都有其特点和适用场景,根据实际情况选择合适的方式来创建对象。工厂模式、构造函数模式、原型模式、混合模式、动态原型模式和寄生构造函数模式都是常用的创建对象的方式。在选择创建对象的方式时,需要注意代码的可读性、可维护性和性能等方面。

持续学习总结记录中,回顾一下上面的内容:
对象创建的方式有很多种。比较常见的包括工厂模式(像工厂一样创建对象)、构造函数模式(使用函数初始化对象)、原型模式(通过原型克隆对象)、混合模式(结合多种方式创建对象)、动态原型模式(在运行时扩展对象功能)、寄生构造函数模式(在构造函数内部创建对象并返回)、字面量方式(直接使用{}创建对象)。这些方式各有特点,可以根据具体需求选择最适合的方式来创建对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/465674.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软和苏黎世联邦理工学院开源SliceGPT创新压缩技术节省大量部署资源;OpenAI成立儿童安全团队,防AI误用

🦉 AI新闻 🚀 微软和苏黎世联邦理工学院开源SliceGPT创新压缩技术节省大量部署资源 摘要:微软和苏黎世联邦理工学院研究人员开源了SliceGPT,通过对大模型的权重矩阵进行压缩切片,实现了模型紧缩,节省了部…

【MySQL】-18 MySQL综合-4(MySQL储存引擎精讲+MySQL数据类型简介+MySQL整数类型+MySQL小数类型)

MySQL储存引擎精讲MySQL数据类型简介MySQL整数类型MySQL小数类型 十一 MySQL存储引擎精讲11.1 什么是存储引擎11.2 MySQL 5.7 支持的存储引擎11.3 如何选择 MySQL 存储引擎11.4 MySQL 默认存储引擎 十二 MySQL数据类型简介12.1 MySQL 常见数据类型1) 整数类型2) 日期/时间类型3…

C语言--------数据在内存中的存储

1.整数在内存中的存储 整数在内存是以补码的形式存在的; 整型家族包括char,int ,long long,short类型; 因为char类型是以ASCII值形式存在,所以也是整形家族; 这四种都包括signed,unsigned两种,即有符号和无符号&am…

nodejs爬虫框架

nodejs爬虫框架 在Node.js中,有一些常用的爬虫框架可以帮助你实现网页抓取和数据提取的任务。以下是几个流行的Node.js爬虫框架: 1. **Puppeteer**: Puppeteer 是由 Google 开发的一个用于控制 headless Chrome 或 Chromium 浏览器的 Node.js 库。它提供…

数据库管理-第149期 Oracle Vector DB AI-01(20240210)

数据库管理149期 2024-02-10 数据库管理-第149期 Oracle Vector DB & AI-01(20240210)1 机器学习2 向量3 向量嵌入4 向量检索5 向量数据库5 专用向量数据库的问题总结 数据库管理-第149期 Oracle Vector DB & AI-01(20240210&#xf…

项目02《游戏-14-开发》Unity3D

基于 项目02《游戏-13-开发》Unity3D , 任务:战斗系统之击败怪物与怪物UI血条信息 using UnityEngine; public abstract class Living : MonoBehaviour{ protected float hp; protected float attack; protected float define; …

掌握高效秘诀:揭秘从容应对多任务管理的终极妙招

多任务管理是非常重要的技能,然而如何平衡任务和时间仍然是许多人的挑战。进行多任务管理一般可以从设定目标和清单、排除无关任务、执行任务的时间块化、利用团队合作、学会任务切换几个方面出发,在本文中我们将详细介绍如何利用有效的多任务管理技巧来…

题目练习(生死时速2.0版)

题目一(Before an Exam) 题意翻译 题目背景 明天皮特将要考生物。他并不很喜欢生物,但在 d 天前他得知他将不得不参加此次考试。皮特严厉的父母勒令他立即复习,因此他在第 i 天将需要学习不少于 minTimei​ 小时,不…

【开源】JAVA+Vue.js实现高校学院网站

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学院院系模块2.2 竞赛报名模块2.3 教育教学模块2.4 招生就业模块2.5 实时信息模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学院院系表3.2.2 竞赛报名表3.2.3 教育教学表3.2.4 招生就业表3.2.5 实时信息表 四、系…

Python访问数据库

目录 SQLite数据库 SQLite数据类型 Python数据类型与SQLite数据类型的映射 使用GUI管理工具管理SQLite数据库 数据库编程的基本操作过程 sqlite3模块API 数据库连接对象Connection 游标对象Cursor 数据库的CRUD操作示例 示例中的数据表 无条件查询 有条件查询 插入…

Linux(Ubuntu) 环境搭建:Nginx

注:服务器默认以root用户登录 NGINX 官方网站地址:https://nginx.org/en/NGINX 官方安装文档地址:https://nginx.org/en/docs/install.html服务器的终端中输入以下指令: # 安装 Nginx apt-get install nginx # 查看版本信息 ngi…