JS宏进阶: 工厂函数与构造函数
一、构造函数
在JavaScript中,构造函数是一种用于创建和初始化对象的特殊函数。构造函数的名字通常以大写字母开头,以区分于普通函数。通过new关键字调用构造函数,可以创建一个新的实例对象,并自动执行构造函数内部的代码来初始化这个对象。
1、构造函数的定义
function Person(name, age) {this.name = name;this.age = age;this.sayHello = function() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);};
}
上述示例,是一个似曾相识的示例。因为在“函数、对象和类(一)”这一章节中简单讲解this关键字时的一个示例。在这个例子中,Person是一个构造函数,它接受两个参数name和age,并将它们赋值给新对象的属性。同时,它还定义了一个方法sayHello。
2、使用new关键字创建实例
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);person1.sayHello(); // 输出: Hello, my name is Alice and I am 30 years old.
person2.sayHello(); // 输出: Hello, my name is Bob and I am 25 years old.
使用new关键字调用Person构造函数,会创建两个新的Person对象person1和person2,它们分别有自己的name和age属性,以及sayHello方法。
3、只能使用new关键字进行实例化
function Person(name, age) {this.name = name;this.age = age;this.sayHello = function() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);};
}function Person1(name, age) {if (!(this instanceof Person1)) throw new Error("只能通过new实例化");this.name = name;this.age = age;this.sayHello = function() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);};
}let p = Person(); //不报错
let p1 = Person1(); //抛出异常
效果图如下所示:
4、构造函数执行过程
创建一个新的空对象。
将这个新对象的__
proto__
属性指向构造函数的prototype对象。
在新对象的上下文中执行构造函数的代码(即this指向新对象)。
如果构造函数没有显式返回对象,则默认返回新对象。
4.1、prototype属性
每个构造函数都有一个prototype属性,这是一个对象,包含应该由构造函数的所有实例共享的属性和方法。
function Person(name, age) {this.name = name;this.age = age;
}Person.prototype.greet = function() {console.log(`Hi, I'm ${this.name}.`);
};const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);person1.greet(); // 输出: Hi, I'm Alice.
person2.greet(); // 输出: Hi, I'm Bob.
在构造函数外部,可以通过prototype属性在构造函数的原型链添加新的方法,如上述示例中,使用Person.prototype.greet = function(){} 的形式为Person对象添加了一个新的方法greet。
4.2、this关键字的用途
this是引用当前对象的属性或方法的关键字,在ES6类中,指向的是类的实例。上述每一个示例中都使用到了this关键字。
5、优点和缺点
优点:
- 构造函数提供了一种方便的方式来创建和初始化对象。
- 通过prototype可以实现方法和属性的共享,节省内存。
缺点:
- 每个实例上的方法(如果不在prototype上定义)不会共享,会浪费内存。
- 使用构造函数创建对象相对于使用对象字面量或类(ES6引入)来说,语法上稍显繁琐。
二、工厂函数
在JavaScript中,工厂函数是一种创建对象的模式,它不同于使用构造函数或类的方式。工厂函数是一个普通的函数或者说是一个高阶函数,它返回一个新对象,而不是使用new关键字来实例化对象。这种模式在需要创建多个相似对象时非常有用,尤其是在不需要使用原型链继承或类的复杂结构时。
1、特点
简单性和灵活性:
工厂函数是普通的函数,因此它们比使用class或构造函数更简单和灵活。你可以轻松地返回不同类型的对象,或者根据需要添加额外的逻辑来创建对象。
不依赖new关键字:使用工厂函数时,不需要使用new关键字来创建对象,这减少了错误的可能性(例如忘记使用new)。
无原型链继承的复杂性:工厂函数创建的对象不会自动共享方法或属性通过原型链,这有时可以简化代码,尤其是当不需要这种共享时。
易于理解和使用:工厂函数的代码通常更易于理解和维护,特别是对于不熟悉JavaScript原型链和构造函数的人来说。
2、示例
function createPerson(name, age) {return {name: name,age: age,greet: function() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);}};
}const alice = createPerson('Alice', 30);
const bob = createPerson('Bob', 25);alice.greet(); // 输出: Hello, my name is Alice and I am 30 years old.
bob.greet(); // 输出: Hello, my name is Bob and I am 25 years old.
3、工厂函数的优势
- 语法简洁性:工厂函数通常比构造函数更简洁,因为它们不需要使用
new
关键字。 - 原型链继承:构造函数允许通过原型链共享方法和属性,这在需要节省内存或实现继承时很有用。工厂函数创建的对象不会自动共享这些方法或属性,但你可以通过其他方式(如使用Object.create或手动复制方法)来实现共享。
- 实例识别:使用构造函数创建的对象可以通过
instanceof
操作符识别为特定构造函数的实例。工厂函数创建的对象没有这种内置的实例识别机制。
三、工厂函数与构造函数的比较
工厂函数 | 构造函数 | |
---|---|---|
定义 | 普通的函数,用于创建并返回一个对象 | 特殊的函数,用于创建对象,需要使用new 关键字 |
灵活性 | 高,可以创建不同类型或结构的对象 | 较低,通常用于创建具有相同结构和行为的对象 |
代码简洁性 | 简洁,不需要使用new 关键字 | 复杂,需要使用new 关键字,并注意this 的指向 |
实例识别 | 无法通过instanceof 识别对象类型 | 可以通过instanceof 识别对象类型 |
原型链继承 | 无法自动通过原型链共享方法和属性 | 可以通过原型链共享方法和属性 |
使用场景 | 适用于需要创建不同类型或结构对象的场景 | 适用于需要创建具有相同结构和行为对象的场景 |
四、总结
工厂函数和构造函数都是JavaScript中用于创建对象的常见模式。它们各有特点,适用于不同的场景。选择哪种模式主要取决于项目的具体需求和代码的复杂性。在实际开发中,可以根据需要灵活选择使用哪种模式来创建对象。
相关文章:

JS宏进阶: 工厂函数与构造函数
一、构造函数 在JavaScript中,构造函数是一种用于创建和初始化对象的特殊函数。构造函数的名字通常以大写字母开头,以区分于普通函数。通过new关键字调用构造函数,可以创建一个新的实例对象,并自动执行构造函数内部的代码来初始化…...

【Linux】线程全解:概念、操作、互斥与同步机制、线程池实现
🎬 个人主页:谁在夜里看海. 📖 个人专栏:《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长,行则将至 目录 📚一、线程概念 📖 回顾进程 📖 引入线程 📖 总结 &a…...
关于ubuntu命令行连接github失败解决办法
如果发现ping github.com有问题 使用sudo gedit /ect/hosts 打开host文件 添加 140.82.114.4 github.com 发现使用git 克隆失败,出现 aliaubuntu:~/文档/ctest$ git clone https://github.com/LearningInfiniTensor/learning-cxx.git 正克隆到 ‘learning-cxx’… …...
# [游戏开发] [Unity游戏开发]3D滚球游戏设计与实现教程
在这篇文章中,我们将通过一个简单的3D滚球游戏的设计与实现,讲解游戏开发中的一些关键概念和技术。游戏的核心目标是让玩家控制一个小球在跑道上左右移动,躲避障碍物并尽量向前跑,直到成功或失败。通过这一过程,我们会涉及到功能点分析、场景搭建、主体控制、游戏机制等多…...

强推未发表!3D图!Transformer-LSTM+NSGAII工艺参数优化、工程设计优化!
目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Transformer-LSTMNSGAII多目标优化算法,工艺参数优化、工程设计优化!(Matlab完整源码和数据) Transformer-LSTM模型的架构:输入层:多个变量作…...
Flutter中的事件冒泡处理
在 Flutter 中,GestureDetector 的点击事件默认是冒泡的,即如果嵌套了多个 GestureDetector,点击事件会从最内层的 GestureDetector 开始触发,然后依次向外层传递。如果你希望控制事件的优先级或阻止事件冒泡,可以使用…...
昇腾环境ppstreuct部署问题记录
测试代码 我是在华为昇腾910B3上测试的PPStructure。 import os import cv2 from PIL import Image #from paddleocr import PPStructure,draw_structure_result,save_structure_res from paddleocr_asyncio import PPStructuretable_engine PPStructure(show_logTrue, imag…...
基于 Python 的财经数据接口库:AKShare
AKShare 是基于 Python 的财经数据接口库,目的是实现对股票、期货、期权、基金、外汇、债券、指数、加密货币等金融产品的基本面数据、实时和历史行情数据、衍生数据从数据采集、数据清洗到数据落地的一套工具,主要用于学术研究目的。 安装 安装手册见…...

电力场景红外测温图像绝缘套管分割数据集labelme格式2436张1类别
数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):2436 标注数量(json文件个数):2436 标注类别数:1 标注类别名称:["arrester"] 每个类别标注的框数&am…...

数字艺术类专业人才供需数据获取和分析研究
本文章所用数据集:数据集 本文章所用源代码:源代码和训练好的模型 第1章 绪论 1.1研究背景及意义 随着社会经济的迅速发展和科技的飞速进步,数字艺术类专业正逐渐崛起,并呈现出蓬勃发展的势头。数字艺术作为创作、设计和表现形式的…...

Java中json的一点理解
一、Java中json字符串与json对象 1、json本质 json是一种数据交换格式。 常说的json格式的字符串 > 发送和接收时都只是一个字符串,它遵循json这种格式。 2、前后端交互传输的json是什么? 前后端交互传输的json都是json字符串 比如:…...

Vue项目搭建教程超详细
目录 一. 环境准备 1. 安装node.js 2. 安装Vue cli 二. 创建 Vue 2 项目 1. 命令行方式 2. vue ui方式 一. 环境准备 1. 安装node.js 可参考node.js卸载与安装超详细教程-CSDN博客 2. 安装Vue cli npm install -g vue/cli检查是否安装成功 vue --version Vue CLI …...

2025年01月蓝桥杯Scratch1月stema选拔赛真题—美丽的图形
美丽的图形 编程实现美丽的图形具体要求: 1)点击绿旗,角色在舞台中心,如图所示; 2)1秒后,绘制一个边长为 140的红色大正方形,线条粗细为 3,正方形的中心为舞台中心,如图所示; 完整题目可点击下…...

【React】插槽渲染机制
目录 通过 children 属性结合条件渲染通过 children 和 slot 属性实现具名插槽通过 props 实现具名插槽 在 React 中,并没有直接类似于 Vue 中的“插槽”机制(slot)。但是,React 可以通过 props和 children 来实现类似插槽的功能…...
计算机网络 | 什么是公网、私网、NAT?
关注:CodingTechWork 引言 计算机网络是现代信息社会的基石,而网络通信的顺畅性和安全性依赖于有效的IP地址管理和网络转换机制。在网络中,IP地址起到了标识设备和进行数据传输的核心作用。本文将详细讨论公网IP、私网IP以及NAT转换等网络技…...
如何解决Outlook无法连接到服务器的问题
Microsoft Outlook 是一款广泛使用的电子邮件客户端,它能够帮助用户高效地管理邮箱、日历和任务。然而,尽管其功能强大,用户有时会遇到“Outlook无法连接到服务器”的问题。这种问题通常会让用户无法接收或发送电子邮件,甚至可能导…...

vue2 web 多标签输入框 elinput是否当前焦点
又来分享一点点工作积累及解决方案 产品中需要用户输入一些文字后按下回车键生成标签来显示在页面上,经过尝试与改造完成如下: <template><div class"tags-view" click"beginInput"><el-tag :key"index" …...
32单片机综合应用案例——物联网(IoT)环境监测站(四)(内附详细代码讲解!!!)
无论你身处何种困境,都要坚持下去,因为勇气和毅力是成功的基石。不要害怕失败,因为失败并不代表终结,而是为了成长和进步。相信自己的能力,相信自己的潜力,相信自己可以克服一切困难。成功需要付出努力和坚…...

LabVIEW与WPS文件格式的兼容性
LabVIEW 本身并不原生支持将文件直接保存为 WPS 格式(如 WPS 文档或表格)。然而,可以通过几种间接的方式实现这一目标,确保您能将 LabVIEW 中的数据或报告转换为 WPS 可兼容的格式。以下是几种常见的解决方案: 导出…...
小结: 路由协议的演进和分类
路由协议的演进和分类,包括其发展历史及主要应用场景。路由协议用于在网络中确定数据传输的最佳路径,主要分为内部网关协议(IGP)和外部网关协议(EGP) AS-AS 之间的。 路由协议的演进 1982年:出…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...