JavaScript对象的构造函数和new操作符(实例详解)

本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript对象的构造函数和new操作符(实例详解)

【相关推荐:javascript视频教程、web前端】

23.JavaScript对象的构造函数和操作符new

一、前言

前文讲到的对象创建方法都是直接使用let obj = {...}语法,具体方法如下:

let user = {    name:'xiaoming',    ...}

这样的对象创建方法虽然简单又直接,但是对象的代码无法重用,在创建很多类似对象时,代码量会很高。

立即学习“Java免费学习笔记(深入)”;

此时,就需要使用构造函数,和new操作符实现相似对象的构建。

二、构造函数

如果学习过其他面向对象语言的童鞋对构造方法应该都不陌生,尤其是学习C++的童鞋应该印象会非常深刻。

构造函数概念和用途

在其他面向对象的语言中,构造函数通常是这样定义的:

构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员都有一个合适的初始值,并且在对象的生命周期内只调用一次。

我们可以简单的理解为,构造函数是所有对象的成员方法中,最早被调用的那个。常用于初始化对象的状态,例如人的名字、火车的节数等。

和构造函数对应的是析构函数,析构函数是所有对象的成员方法中,最后被调用的那个,常常是对象失去存在价值,用于回收对象资源。

对象的生命周期

一个对象从创建到回收,总共可以划分为3个阶段,如下图:

image-20220509094804084

其中,对象创建阶段的主要工作由构造函数完成,包括对象的初始化,关系的连接等。执行阶段主要是对象功能的调用,用于配合整个项目的执行,通常由普通函数(对象的成员函数)完成。销毁阶段由析构函数接手,用于清除对象占用的内存空间,防止内存泄漏的发生。

JavaScript构造函数

相比于其他面向对象语言,JavaScript对象的构造函数比较特殊,它可以是任何一个普通的函数,而且无需在对象中定义。只有两个约定:

构造函数的命名通常以大写开头;构造函数智能由new操作符执行;

例如:

function People(name){    this.name = name;}

以上代码中的People函数就可以当作构造函数使用,同时它也是一个普通的函数。对象的this指针章节,我们介绍过,如果一个普通函数中使用thisthis的内容取决于调用它的对象(obj.func()),如果不使用对象调用函数,那么this在非严格模式下就是Window,严格模式下就是undefined

通常情况下,直接调用构造函数会得到不正确的结果,如果我们希望把函数当作构造函数调用,就需要使用一个新的关键字new

以下代码使用new关键字创建了两个People对象:

let xiaoming = new People('xiaoming');let xiaohong = new People('xiaohong');console.log(xiaoming.name);console.log(xiaohong.name);

以下是代码的执行结果:

image-20220509101014388

三、new 关键字

当使用new调用一个函数时,这个函数就会变成构造函数,此时,引擎就会执行以下动作:

创建一个新的空对象{ },并把空对象赋值给this;执行构造函数体,通常会通过this构造对象的内部结构;返回this的值;

你没有看错,使用new调用函数后,函数是有返回值的,即使在定义函数时没有return语句。

代码new People('xiaoming')所做的事情大概类似以下代码:

function People(name){    this = {};//隐式的创建一个空对象    this.name = name;    return this;//把创建的对象返回}

所以使用new调用构造函数后,得到的是一个由构造函数塑造过的对象。

使用new关键字的好处是,我们可以书写一次构造函数代码,然后在任意的地方创建类似的对象。

例如:

let xiaoming = new People('xiaoming');let xiaohong = new People('xiaohong');let mingming = new People('mingming');

想象一下,如果对象的代码有上百行,这么做是不是比{...}方式要简便很多呢?这就是面向对象中的代码服用,可以极大程度上降低代码量,提高开发速度。

如果构造函数没有参数,我们可以省略调用时的括号:

let xiaoming = new People;//类似于这样let xiaoming = new People();//等价于这样

但是个人推荐不要使用这种特性,仅仅是告知在规范中存在这种语法。

即构数智人 即构数智人

即构数智人是由即构科技推出的AI虚拟数字人视频创作平台,支持数字人形象定制、短视频创作、数字人直播等。

即构数智人 36 查看详情 即构数智人

强调:

从技术上讲,任何函数(除了箭头函数,它没有自己的 this)都可以用作构造器。即可以通过 new 来运行,它会执行上面的算法。“首字母大写”是一个共同的约定,以明确表示一个函数将被使用 new 来运行。

四、匿名构造函数

如果我们只希望对象被创建一次,那么就可以简化构造函数的定义,使用new直接调用匿名函数,创建一个对象:

let xiaoming = new function(){    this.name = 'xiaoming';}console.log(xiaoming.name);

代码的执行结果如下:

image-20220509103028104

使用匿名函数当作构造函数的结果和常规构造函数没有任何区别,唯一的区别是匿名构造函数不能重复调用(因为没有名字)。这种使用方法常用在无需复用代码的场景中。

五、构造函数的返回值

常规情况下,构造函数不需要使用return语句,它的唯一用途就是把对象的属性写入this,然后直接默认返回this对象就好了。

但是,由于JavaScript对构造函数几乎没有任何约束,如果我们在一个普通函数中写了返回语句,会发生什么呢?引擎会做下面两个选择:

如果return返回的是一个对象,就返回这个对象,不再返回this;如果return返回的是一个基础类型,则忽略返回语句,继续返回this

从引擎的处理方式中不难看出,构造函数的主要任务就是创建对象,处理并返回,如果使用构造函数返回一个基础类型,是没有意义的。

举个栗子:

function People(name){    this.name = name;return {name:'Nobody'};}console.log(new People('xiaoming').name);

代码执行结果如下:

image-20220509104829230

可以看出,name为’xiaoming’的对象没有被返回,而是Nobody对象代替了xiaoming

如果使用return返回一个基础类型,案例如下:

function Dog(){    this.name = 'hashiqi';return 666;}console.log(new Dog().name);

代码执行结果如下:

image-20220509114432485

可见,在返回基础类型时,return语句是不生效的。

强调:

通常对象的构造函数没有返回值,我们也没有必要利用引擎对构造函数返回值的特殊处理,编写特别的构造函数。

六、利用构造函数为对象添加方法

在构造函数中不仅可以添加对象的属性,由于JavaScript的函数同样可以赋值给变量,我们还可以用构造函数初始化对象的成员方法。

例如,我们可以给People对象增加一个sing方法:

function People(name){    this.name = name;    this.sing = function(){        console.log(`${name} is a happy boy.`);    }}let xiaoming = new People('xiaoming');xiaoming.sing();

以上代码在构造函数中为对象添加了一个方法,代码执行结果如下:

image-20220509115253349

结语

截止到目前,我们介绍的对象都只是以JavaScript的一个特殊数据类型(数据结构)角度出发的,实际上,在面向对象领域,类才是绝对的主角。

我们会在后文逐步深入介绍JavaScript的各种特性,包括面向对象知识,类、继承等。

总结

本文主要介绍了JavaScript对象的构造方法和new关键字,需要掌握并注意的点包括:

构造函数是一个常规函数,但是有一些首字母大写的约定;箭头函数由于没有this,因此不能作为构造函数;构造函数需要使用new关键字调用,并返回一个对象;当构造函数本身拥有返回语句时,引擎会做特殊处理;

【相关推荐:javascript视频教程、web前端】

以上就是JavaScript对象的构造函数和new操作符(实例详解)的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/550620.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月9日 19:54:17
下一篇 2025年11月9日 19:58:02

相关推荐

  • Go语言结构体属性的动态访问:使用reflect包

    go语言通常通过直接字段名访问结构体属性,但若需在运行时根据字符串名称动态获取属性值,标准语法无法实现。本文将深入探讨如何利用go的`reflect`包来解决这一需求,提供示例代码,并分析其性能、类型安全及错误处理等方面的考量,指导开发者在特定场景下合理使用反射机制。 理解Go结构体属性访问的本质 …

    2025年12月16日
    000
  • 如何在Golang中实现Web静态文件缓存_Golang Web静态文件缓存方法汇总

    答案:Go中常用静态文件缓存方法包括设置Cache-Control头、使用ServeFile、内存缓存、ETag协商及embed嵌入。1. 用http.FileServer配合中间件设置max-age实现强缓存;2. 通过http.ServeFile按路径动态控制缓存策略,结合contenthash…

    2025年12月16日
    000
  • 解决Set-Cookie头在HTTP请求中失效的指南

    本文旨在解决`set-cookie`头在浏览器中不生效的问题,即便响应中明确包含了该头。核心原因是`secure`标志的使用不当:当服务器通过`set-cookie`头设置了`secure`标志,但客户端通过非加密的http协议访问时,浏览器会出于安全考虑拒绝存储该cookie。教程将详细解释`se…

    2025年12月16日
    000
  • 如何在Golang中实现动态字段值更新

    答案:在Golang中通过reflect包实现动态字段更新,需传入结构体指针,使用FieldByName查找可导出字段并调用Set赋值,结合类型检查与转换可支持灵活更新,适用于ORM等场景。 在Golang中实现动态字段值更新,关键在于使用反射(reflect包)来操作结构体字段。由于Go是静态类型…

    2025年12月16日
    000
  • Golang如何处理Web表单上传进度显示

    Go语言通过后端接口支持上传进度,前端利用HTML5事件监听、分片上传查询、第三方协议或实时推送实现进度显示。 Go语言本身不直接提供前端上传进度功能,因为进度显示主要依赖前端技术配合后端支持。但Golang可以通过后端接口设计和中间件机制,为文件上传进度的实现提供数据支撑。要实现Web表单上传进度…

    2025年12月16日
    000
  • Go html/template:在 HTML 中安全地嵌入 JSON 数据

    本文探讨了在 go 的 `html/template` 包中,如何在不使用 “ 标签的情况下,将 go 数据结构作为 json 字符串安全地嵌入到 html 内容中。我们将介绍两种主要方法:利用 `encoding/json` 进行数据序列化并结合 `template.html` 类型来…

    2025年12月16日
    000
  • 如何在Golang中处理cookie和token

    答案:在Golang中通过net/http设置Cookie使用http.SetCookie,读取用r.Cookie,Token常用JWT实现,生成后可通过Cookie或Header传输,结合HttpOnly、Secure、SameSite可提升安全性,验证时解析Authorization头或Cook…

    2025年12月16日
    000
  • Go语言JSON解码:处理数字字符串键到整数键映射的策略

    本文探讨了在go语言中处理json数据时,如何将以数字字符串作为键的json对象有效转换为以整数作为键的go `map`类型。由于json规范仅支持字符串键,go的`encoding/json`包无法直接解码为`map[int]type`。文章详细介绍了先解码为`map[string]type`,然…

    2025年12月16日
    000
  • Golang如何实现简单的用户消息通知

    使用WebSocket实现Golang消息通知,通过gorilla/websocket库建立持久连接,每个连接由独立goroutine处理;利用全局map存储用户ID与连接的映射关系,登录时注册,断开时清理;发送通知时查表并写入JSON消息;前端通过JavaScript监听消息并更新UI,支持重连机…

    2025年12月16日
    000
  • 如何在Golang中调用动态函数并获取返回值

    答案是使用反射机制可实现Go语言的动态函数调用。通过reflect.ValueOf获取函数值,Call传入参数并调用,再从返回的[]reflect.Value中提取结果,支持多返回值和结构体方法调用,适用于插件系统等场景。 在Go语言中,调用动态函数并获取返回值通常依赖反射(reflect包)。由于…

    2025年12月16日
    000
  • 前端资源异步加载与性能优化

    异步加载通过非阻塞方式提升页面性能。使用 async、defer 和动态脚本实现 JS 异步加载;内联关键 CSS、异步加载非关键样式优化 CSS;图片采用 lazy loading 与响应式加载;结合 preload、prefetch 提升资源优先级,合理运用可显著优化首屏渲染与用户体验。 前端资…

    2025年12月16日
    000
  • Go语言中JSON整数键的解码与高效转换实践

    本文深入探讨了go语言`encoding/json`包在处理json对象时,为何其键必须为字符串类型,以及当json数据包含数字作为键时,如何高效地将其解码并转换为`map[int]t`类型。文章将提供详细的解释和实用的go代码示例,帮助开发者理解并实现这一转换过程,确保数据处理的准确性和内存效率。…

    2025年12月16日
    000
  • Go语言中处理JSON对象整数键的策略与实践

    本文探讨了在go语言中处理json数据时,如何解决json标准仅支持字符串键而实际数据可能包含整数键的问题。我们将解释`encoding/json`包的默认行为,并提供一种高效且内存友好的方法,通过在解码后将字符串键转换为整数来实现`map[int]float32`等结构,同时包含示例代码和注意事项…

    2025年12月16日
    000
  • Go语言中JSON整数键的解码与高效转换策略

    在go语言中处理json数据时,由于json标准规定对象键必须是字符串,`encoding/json`包默认也只支持字符串键。因此,无法直接将包含整数键的json解码为`map[int]t`类型。本文将详细探讨这一限制,并提供一种高效且内存友好的两步解决方案:首先解码为`map[string]t`,…

    2025年12月16日
    000
  • Go语言中将JSON字符串键转换为整型键映射的策略与实践

    go语言的`encoding/json`包遵循json规范,只支持字符串键。因此,无法直接将json中的数字字符串键解码为`map[int]type`。本文将详细介绍如何先解码为`map[string]type`,然后通过迭代和`strconv.atoi`函数高效地将字符串键转换为整型键,从而实现`…

    2025年12月16日
    000
  • Go模板中{{$}}占位符的深入解析与动态WebSocket URL构建

    “).text(evt.data)) } } else { appendLog($(“ Your browser does not support WebSockets. “)) } $(“#form”).submit(function (…

    2025年12月16日
    000
  • Go语言中模拟JavaScript短路求值实现多选项变量赋值

    本文探讨了如何在go语言中实现类似javascript的短路求值(`||`操作符)来从多个选项中赋值变量。go语言强调类型安全,不直接支持非布尔类型的“真值”判断,也无三元运算符。教程将展示使用`if/else if/else`结构进行条件赋值的标准go语言实践,并强调其清晰性和类型安全的重要性。 …

    2025年12月16日
    000
  • 深入理解Go encoding/xml中omitempty与指针的反序列化行为

    本文旨在阐明go语言`encoding/xml`包中`omitempty`标签在处理指针类型时的反序列化(unmarshal)行为。许多开发者误以为`omitempty`能阻止空xml元素初始化指针字段,但实际上它仅影响序列化(marshal)。我们将通过具体示例,解析为何在空xml元素(如&#82…

    2025年12月16日
    000
  • 如何在Golang中实现任务列表拖拽功能

    Golang不直接实现拖拽,而是通过API支持前端拖拽功能。前端使用HTML5或SortableJS实现任务项拖动,用户调整顺序后,JavaScript将新顺序(如[2, 1])通过POST请求发送至Golang后端。后端定义/api/reorder接口,接收包含任务ID数组的JSON数据,遍历并更…

    2025年12月16日
    000
  • 如何在Golang中开发小型CRM系统

    先定义客户结构体并实现REST API,再通过net/http搭建路由,结合SQLite完成增删改查。1. 设计Customer结构体包含ID、Name、Email等字段;2. 使用net/http创建GET/POST/PUT/DELETE路由处理请求;3. 用database/sql和mattn/…

    2025年12月16日
    000

发表回复

登录后才能评论
关注微信