【前端】JavaScript 中的创建对象模式要点
文章目录
- 💯前言
- 💯对象属性值中的引号规则
- 💯对象属性换行与尾随逗号的使用
- 💯工厂模式:灵活高效的对象创建
- 💯自定义构造函数:通过 `new` 创建对象
- 💯`instanceof` 的作用与原型链
- 工厂模式的 `instanceof`
- 自定义构造函数的 `instanceof`
- 💯 工厂模式与自定义构造函数的对比
- 💯小结
💯前言
- 在 JavaScript 的研究和应用中,深入理解对象的创建方式至关重要。无论是初学者还是经验丰富的开发者,JavaScript 的
工厂模式
与自定义构造函数模式
都是需要全面掌握的知识点。在本文中,我们将详细探讨这些模式,包括它们的使用方式、各自的优劣、以及在特定场景中的适用性。通过对这些模式的深刻理解,读者可以更好地掌握 JavaScript 中的面向对象编程技术,从而撰写出具备高度扩展性
和可维护性
的代码。
JavaScript
💯对象属性值中的引号规则
首先,需要理解如何在 JavaScript 中正确地为对象属性赋值。对象的属性值可以有多种类型,其中字符串类型的值必须用引号包裹(可以是单引号'
或双引号"
),而其他类型的值,如数字
、布尔值
等,则无需引号。这种区别对于代码的可读性和减少错误尤为重要,尤其在复杂的应用程序或大型项目中,保持代码风格的一致性是提高开发效率
和可维护性
的重要因素。
例如:
var obj = {name: 'Alice', // 字符串类型,必须用引号age: 25, // 数字类型,不需要引号isStudent: true // 布尔值,不需要引号
};
在上述代码中,name
属性的值是字符串,因此必须用引号包裹,而 age
和 isStudent
则是数字和布尔类型,因此没有使用引号。这些细节对于避免低级语法错误、提高代码一致性和可读性具有重要意义。同时,这种约定也有助于团队成员之间的协作,确保代码风格统一,使得代码更容易被理解和维护。
💯对象属性换行与尾随逗号的使用
在编写对象时,经常会遇到需要添加多个属性的情况。为了提高代码的可读性,通常会将每个属性分行书写,并用逗号进行分隔。在这种情况下,最后一个属性的后面可以选择加逗号,也可以不加逗号,在现代 JavaScript 中这两种方式都是合法的。这种灵活性不仅使代码更加清晰,同时也在修改对象时减少了可能的错误。
例如:
var student = {name: 'Bob',age: 22,gender: 'Male', // 最后的逗号是可选的
};
这种书写方式被称为**“尾随逗号”,它的主要优势在于当需要为对象添加新属性时,可以避免对之前最后一行的属性进行修改,从而降低修改引入错误的风险。在大型代码库或复杂的对象结构中,使用尾随逗号
可以显著减少人为失误,尤其是在多人协作的开发环境下**,这种书写规范可以让代码的维护更加轻松和高效。
💯工厂模式:灵活高效的对象创建
在 JavaScript 中,工厂模式是一种通过函数创建并返回对象的设计模式。工厂模式的主要优势在于可以灵活地创建对象,而不必依赖 new
关键字。这种模式特别适合需要根据参数动态生成不同类型对象的场景,极大地提高了代码的复用性和灵活性。它使得我们能够在函数内部决定返回什么样的对象,而不需要拘泥于特定的构造函数。
例如:
function createStudent(name, age, sex) {var obj = new Object();obj.name = name;obj.age = age;obj.sex = sex;obj.speak = function () {console.log('我要学习, 学习使我快乐, 学习让我成长!');};return obj;
}var student1 = createStudent('小明', 18, 'Male');
在上述例子中,createStudent
是一个工厂函数,它创建了一个新的对象 obj
,根据传入的参数为对象赋值,并最终返回这个对象。工厂模式的一个重要特征就是它不需要 new
关键字来调用,而是直接返回新对象。这种灵活性使得工厂模式在处理创建结构相似但配置不同的对象时显得尤为便利,尤其在需要根据不同输入生成具有不同配置的对象时,工厂模式提供了极大的便利。
此外,工厂模式还可以通过封装复杂逻辑来简化对象的创建过程,使代码更加简洁并且易于测试。例如,如果我们需要创建不同类型的学生对象,可以根据传递的 type
参数返回不同的对象,而无需为每种类型的对象定义不同的构造函数。
💯自定义构造函数:通过 new
创建对象
与工厂模式不同,自定义构造函数依赖于 new
关键字来创建对象。构造函数的定义方式与普通函数类似,但通常第一个字母大写,以示区分。构造函数通过使用 this
关键字来定义对象的属性和方法,属性和方法都会绑定到新创建的实例上。
例如:
function Student(name, age, sex) {this.name = name;this.age = age;this.sex = sex;this.speak = function () {console.log('我要学习, 学习使我快乐, 学习让我成长! 我叫 ' + this.name);};
}var student2 = new Student('张三', 20, 'Male');
在这个例子中,Student
是一个构造函数,使用 new Student('张三', 20, 'Male')
可以创建一个新的实例 student2
。构造函数的核心特征是它通过 new
关键字来调用,this
关键字指向新创建的对象实例,因此可以通过 this
来为对象添加属性和方法。通过 new
关键字创建的对象不仅可以确保独立实例之间的隔离性,同时能够复用构造函数定义的逻辑。
构造函数的一个显著优点是它可以结合 prototype
实现方法的共享。将方法定义在构造函数的原型对象上,而不是在构造函数内部定义,可以避免每个实例都创建一个独立的方法,这样既节省了内存,又保持了一致性。例如,可以将 speak
方法放在 Student.prototype
上,使得所有实例共享同一个 speak
方法,这在需要大量创建对象的场景中尤为重要。
💯instanceof
的作用与原型链
在 JavaScript 中,instanceof
用于检查一个对象是否为某个构造函数的实例。instanceof
的原理是沿着对象的原型链(prototype chain)进行查找,如果对象的原型链中存在与构造函数的 prototype
属性相等的原型,instanceof
就会返回 true
。这使得 instanceof
成为实现继承和检查对象类型的重要工具。
例如:
console.log(student2 instanceof Student); // true
console.log(student2 instanceof Object); // true
在上述例子中,student2
是通过 Student
构造函数创建的,因此 student2 instanceof Student
为 true
。由于所有对象的原型链最终都会指向 Object.prototype
,因此 student2 instanceof Object
也为 true
。这种类型检查方法对于确保代码的可靠性和健壮性非常有效,特别是在构建复杂的对象体系结构时。
工厂模式的 instanceof
通过工厂模式创建的对象,因为没有通过 new
绑定到特定的构造函数,因此这些对象与工厂函数之间没有直接的原型链关系。因此,使用 instanceof
检测工厂模式创建的对象时,结果通常不会与工厂函数关联。
例如:
function createStudent(name, age, sex) {var obj = new Object(); //new 构造函数();obj.name = name;obj.age = age;obj.sex = sex;obj.speak = function () {console.log('我要学习,学习使我快乐,学习让我成长!');}return obj;
}
var stu1 = createStudent('小明', 99, 'Man');console.log(stu1 instanceof createStudent); // false
console.log(stu1 instanceof Object); // true
在上述代码中,stu1
是通过工厂函数创建的普通对象,但它并没有与 createStudent
函数建立任何原型链上的关联,因此 stu1 instanceof createStudent
返回 false
。然而,由于所有通过对象字面量或 new Object()
创建的对象最终都是 Object
的实例,因此 stu1 instanceof Object
返回 true
。这表明,工厂模式创建的对象在类型检查方面是相对弱化的,而通过构造函数模式创建的对象则具有更强的类型关联。
这种差异意味着,如果需要通过 instanceof
来判断某个对象是否是某个类型的实例,那么工厂模式并不适合,因为工厂函数返回的对象与它们没有直接的原型链关系。而构造函数模式通过 prototype
属性使对象与构造函数保持了联系,因此 instanceof
在这种模式下可以提供可靠的类型检查。
自定义构造函数的 instanceof
通过自定义构造函数创建的对象能够可靠地通过 instanceof
检查。这是因为通过 new
关键字调用构造函数时,JavaScript 会自动将新创建的对象的原型(__proto__
)指向构造函数的 prototype
,从而形成了正确的原型链关系。
例如:
function Student(name, age, sex) {this.name = name;this.age = age;this.sex = sex;this.speak = function () {console.log('我要学习, 学习使我快乐, 学习让我成长! 我叫 ' + this.name);};
}var stu3 = new Student('张三', 18, 'Man');console.log(stu3 instanceof Student); // true
console.log(stu3 instanceof Object); // true
在上述例子中,stu3
是通过 Student
构造函数创建的对象,因此 stu3 instanceof Student
为 true
。这表明 stu3
的原型链中包含 Student.prototype
。同时,stu3
也是 Object
的实例,因为所有的对象最终都继承自 Object
,因此 stu3 instanceof Object
也为 true
。
这种可靠的原型链关系使得通过构造函数模式创建的对象能够进行精确的类型判断,尤其是在复杂的应用场景中,这种机制对于确保对象的正确性和类型安全性尤为重要。它使得构造函数模式在需要进行严格类型检查和继承的场景中显得更为适用。
💯 工厂模式与自定义构造函数的对比
特性 | 工厂模式 (createStudent ) | 自定义构造函数 (Student ) |
---|---|---|
instanceof 检测结果 | false | true |
对象与函数的关联 | 没有关联,返回普通对象 | 对象与构造函数的 prototype 有关联 |
使用方式 | 普通函数调用,返回一个独立对象 | 必须使用 new 关键字 |
原型链机制 | 与工厂函数无关 | 实例通过原型链指向构造函数的 prototype |
灵活性 | 可以动态返回不同类型的对象 | 只能返回固定的构造对象 |
在实际开发中,工厂模式适用于需要灵活创建不同类型对象
的场景,而自定义构造函数模式则更适合于需要共享方法和属性
的对象创建场景。构造函数模式通过prototype
实现了方法的共享,因而在需要创建大量相似对象时更为高效,而工厂模式由于其动态特性则在处理变化较多的对象结构时表现得更好。在某些复杂的场景中,两者可以结合使用,以充分发挥它们各自的优势。例如,通过工厂函数
来包装构造函数,从而在创建对象时既能享受构造函数的性能优势,又能够保持工厂模式的灵活性。
💯小结
通过这篇文章,我们深入探讨了 JavaScript 中工厂模式
与自定义构造函数模式
的不同特性与适用场景。工厂模式提供了一种灵活的方式来创建对象,尤其适用于动态需求的场景,而自定义构造函数结合new
关键字,则让我们能够通过原型链共享方法,非常适合需要大量相似对象的场景。掌握这些差异有助于在实际开发中灵活运用,选择最适合的模式,从而编写出更加高效
且可维护
的代码。
除了深入理解 JavaScript 的原型链机制
,理解 ES6 引入的class
语法也是非常重要的。虽然class
本质上是基于原型的语法糖,但它提供了一种更具表现力且易于使用的方式来定义对象和继承关系。通过结合工厂模式
、自定义构造函数
与class
语法,开发者能够更灵活地应对多样的编程需求,编写出结构合理且便于扩展的代码。对这些模式及其底层机制的深刻理解,将使你在 JavaScript 编程的道路上更具信心并能应对各种复杂挑战
。
相关文章:

【前端】JavaScript 中的创建对象模式要点
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 💯前言💯对象属性值中的引号规则💯对象属性换行与尾随逗号的使用💯工厂模式:灵活高效的对象创建💯自定义构造函数:通过…...

GWAS分析先做后学
大家好,我是邓飞。 GWAS分析是生物信息和统计学的交叉学科,上可以学习编程,下可以学习统计。对于Linux系统,R语言,作图,统计学,机器学习等方向,都是一个极好的入门项目。生物信息如…...

【系统设计】高可用之缓存基础
缓存的缘起 使用缓存的主要原因包括提高系统性能、降低数据库负载、提升用户体验和保证系统可用性。 在计算机体系结构中,由于处理器和存储器的处理时间不匹配,在处理器和一个较大较慢的设备之间插入一个更小更快的存储设备(如高速缓存&a…...

《Java核心技术I》volatile字段
volatile字段 有多处理器的计算机能够暂时在寄存器或本地内存缓存中保存内存值,其结果是,运行在不同处理器上的线程可能看到同一个内存位置上有不同的值。编译器可以改变指令执行的顺序以使吞吐量更大化,编译器不会选择可能改变代码语义的顺…...

2024运维故障记 | 12/2 网易云音乐崩了
#运维故障记# 前两天看到网易云音乐崩了的新闻,回想了一下,今年从网易云音乐到支付宝、还有微软,近期就发生了好几起运维届的故障。 今年来不及计数了,先做个记录。 明年看看运维届的大故障会发生多少,什么原因&…...

架构设计读后——微服务
1 微服务历史 2005年:Dr. Peter Rodgers提出"Micro-Web-Services"概念2011年:一个软件架构工作组使用"microservice"来描述一中架构模式2012年;这个工作组正式使用"microservice"来代表这个架构2012年&#x…...

软考高级架构-9.4.4-双机热备技术 与 服务器集群技术
一、双机热备 1、特点: 软硬件结合:系统由两台服务器(主机和备机)、一个共享存储(通常为磁盘阵列柜)、以及双机热备软件(提供心跳检测、故障转移和资源管理功能的核心软件)组成。 …...

聊聊前端工程化
深度解析前端工程化 近年来,随着前端技术的快速迭代和项目复杂度的增加,前端开发已经从简单的页面搭建演变为专业的工程化体系。前端工程化通过工具链、标准化和流程化手段,不仅提高了开发效率,也大幅提升了项目的可维护性和协…...

“放弃Redis Desktop Manager使用Redis Insight”:日常使用教程(Redis可视化工具)
文章目录 更新Redis Insight连接页面基础解释自动更新key汉化暂时没有找到方法, Redis Desktop Manager在连接上右键在数据库上右键在key上右键1、添加连接2、key过期时间 参考文章 更新 (TωT)ノ~~~ βyё βyё~ 现在在维护另一…...

mmdection配置-yolo转coco
基础配置看我的mmsegmentation。 也可以参考b站 :https://www.bilibili.com/video/BV1xA4m1c7H8/?vd_source701421543dabde010814d3f9ea6917f6#reply248829735200 这里面最大的坑就是配置coco数据集。我一般是用yolo,这个yolo转coco格式很难搞定&#…...

聚合支付系统/官方个人免签系统/三方支付系统稳定安全高并发 附教程
聚合支付系统/官方个人免签系统/三方支付系统稳定安全高并发 附教程 系统采用FastAdmin框架独立全新开发,安全稳定,系统支持代理、商户、码商等业务逻辑。 针对最近一些JD,TB等业务定制,子账号业务逻辑API 非常详细,方便内置…...

力扣67. 二进制求和
给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 示例 1: 输入:a "11", b "1" 输出:"100" 示例 2: 输入:a "1010", b "1011" 输出&#…...

网络安全中的 SOC 是什么?
当今世界,网络威胁日益增多,确保网络安全已成为各种规模企业的首要任务。网络安全讨论中经常出现的一个术语是 SOC,即安全运营中心的缩写。但网络安全中的 SOC 是什么呢? SOC在防御网络威胁、管理安全事件和全天候监控系统方面发…...

16、鸿蒙学习——Visibility与(if...else)该如何选择
在鸿蒙中我们如果要控制一个组件的显示与隐藏可以设置组件的Visibility属性,也可使用(if...else)条件控制,具体我们该选择哪个?二者有什么区别呢? 1、Visibility 名称描述Hidden隐藏,但参与布局…...

PH热榜 | 2024-12-05
1. Oopsie 标语:用AI和会话回放调试Flutter和React Native应用 介绍:Zipy推出的Oopsie是一款你唯一需要的AI赋能移动端调试工具,它能提供▶️会话回放、🤖错误监控、💡AI生成的概要分析,以及🔥…...

Qt Chart 模块化封装曲线图
一 版本说明 二 完成示例 此文章包含:曲线轴设置,曲线切换,单条曲线显示,坐标轴。。。 三 曲线图UI创建 在UI界面拖放一个QWidget,然后在 Widget里面放一个 graphicsView 四 代码介绍 1 头文件 #include <QString> #include <QTimer> #include <QMessa…...

【AI系统】MobileFormer
MobileFormer 在本文中,将介绍一种新的网络-MobileFormer,它实现了 Transformer 全局特征与 CNN 局部特征的融合,在较低的成本内,创造一个高效的网络。通过本节,让大家去了解如何将 CNN 与 Transformer 更好的结合起来…...

python数据分析之爬虫基础:解析
目录 1、xpath 1.1、xpath的安装以及lxml的安装 1.2、xpath的基本使用 1.3、xpath基本语法 2、JsonPath 2.1、jsonpath的安装 2.2、jsonpath的使用 2.3、jsonpath的基础语法 3、BeautifulSoup 3.1、bs4安装及创建 3.2、beautifulsoup的使用 3.3、beautifulsoup基本语…...

uniapp中导入uview或者uview plus
关于SCSS uview-plus依赖SCSS,您必须要安装此插件,否则无法正常运行。 如果您的项目是由HBuilder X创建的,相信已经安装scss插件,如果没有,请在HX菜单的 工具->插件安装中找到"scss/sass编译"插件进行安…...

【LeetCode】122.买卖股票的最佳时机II
文章目录 题目链接:题目描述:解题思路一(贪心算法):解体思路二(动态规划): 题目链接: 122.买卖股票的最佳时机II 题目描述: 解题思路一(贪心算法…...

openGauss开源数据库实战十九
文章目录 任务十九 openGauss DML 语句测试任务目标实施步骤一、准备工作二、INSERT语句三、DELETE语句四、UPDATE语句五、清理工作 任务十九 openGauss DML 语句测试 任务目标 掌握DML语句的用法,包括INSERT语句、DELETE语句和UPDATE语句。 实施步骤 一、准备工作 使用Li…...

恶补英语初级第18天,《询问他人的喜好(上)》
对话 Do you like coffee? Yes, I do. Do you want a cup? Yes, please. Do you want any sugar? Yes, please. Do you want any milk? No, thank you. I don’t like milk in my coffee, I like black coffee. Do you like biscuits? Yes, I do. Do you want one? Yes, …...

centos 报 ping: www.baidu.com: Name or service not known
[rootlocalhost ~]$ ping www.baidu.com ping: www.baidu.com: Name or service not known解决办法: 首先要求检查特定文件(/etc/resolv.conf)内是否正确配置了 DNS sudo vim /etc/resolv.conf没有正确配置可以添加如下代码: n…...

Python:使用随机森林分类器进行模型评估:ROC 曲线与 AUC 指标计算
前言 这段代码的目标是使用 随机森林分类器(Random Forest Classifier) 来进行二分类任务,并基于每个数据子集计算 ROC 曲线(Receiver Operating Characteristic Curve)以及 AUC(Area Under Curve…...

数据库表约束完全指南:提升数据完整性和准确性
数据库表约束完全指南:提升数据完整性和准确性 在数据库设计中,表约束是确保数据完整性和准确性的关键工具。本文将详细介绍各种类型的表约束及其使用方法,包括非空约束、唯一约束、主键约束、外键约束、默认值约束、检查约束以及自动递增约…...

【JavaEE】多线程(6)
一、用户态与内核态 【概念】 用户态是指用户程序运行时的状态,在这种状态下,CPU只能执行用户态下的指令,并且只能访问受限的内存空间 内核态是操作系统内核运行时的状态,内核是计算机系统的核心部分,CPU可以执行所有…...

BERT和RoBERTa;双向表示与单向的简单理解
目录 BERT和RoBERTa大型预训练语言模型 BERT的原理 RoBERTa的原理 举例说明 双向表示与单向的简单理解 除了预训练语言模型,还有什么模型 一、模型类型与结构 二、训练方式与数据 三、应用场景与功能 四、技术特点与优势 BERT和RoBERTa大型预训练语言模型 BERT(Bi…...

Pytorch使用手册-计算机视觉迁移学习教程(专题十三)
在本教程中,你将学习如何使用迁移学习训练一个卷积神经网络进行图像分类。更多关于迁移学习的内容可以参考 CS231n 课程笔记。 引用课程笔记中的内容: 实际上,很少有人从头开始训练一个完整的卷积网络(随机初始化),因为拥有足够大数据集的情况相对罕见。相反,通常会在非…...

Jackson - Java对象与JSON相互转换
在这篇文章中,我将向您展示如何使用Jackson-databind API来实现Java对象与JSON之间的绑定,以及如何将JSON数据转换为Java对象。 对于Java开发者来说,将JSON转换为Java对象及反向操作是一个常见的任务,因此我将通过示例演示如何完…...

怎麼解決路由器IP地址衝突?
路由器IP地址衝突通常發生在網路中有兩個設備嘗試使用相同的IP地址時。這種衝突會導致網路連接問題,因為每個設備需要一個唯一的IP地址才能正常通信。 1. 重啟設備 重啟路由器和設備:有時候簡單的重啟可以解決問題,設備重新獲取一個新的IP地…...