JS红宝书笔记 8.2 创建对象

虽然使用Object构造函数或对象字面量可以方便地创建对象,但这些方式有明显不足:创建具有同样接口的多个对象需要重复编写很多代码

工厂模式可以用不同的参数多次调用函数,每次都会返回一个新对象,这种模式虽然可以解决创建多个类似对象的问题,但没有解决对象表示问题,即新创建的对象是什么类型

构造函数和工厂函数的区别:

  • 没有显式的创建对象
  • 属性和方法字节赋值给了this
  • 没有return

使用new操作符调用构造函数会执行如下操作:

  • 在内存中创建一个新对象
  • 这个新对象内部的[[Prototype]]特性被赋值为构造函数的prototype属性
  • 构造函数内部的this被赋值为这个新对象,即this指向新对象
  • 执行构造函数内部的代码,给新对象添加属性
  • 如果构造函数返回非空对象,则返回该对象,否则,返回刚创建的新对象

constructor本来是用于标识对象类型的,不过,一般认为instanceof操作符是确定对象类型更可靠的方式

相比于工厂模式,定义自定义构造函数可以确保实例被标识为特定类型。

构造函数不一定要写成函数声明的形式,赋值给变量的函数表达式也可以表示构造函数,在实例化时,如果不想传参数,那么构造函数后面的括号可加可不加。只要有new操作符,就可以调用相应的构造函数

构造函数与普通函数唯一的区别就是调用方式不同,除此之外,构造函数也是函数,并没有把某个函数定义为构造函数的特殊语法。任何函数只要使用new操作符调用就是构造函数,而不是用new操作符调用的函数就是普通函数。

构造函数的主要问题在于,其定义的方法会在每个实例上都创建一遍,因为都是做一样的事,所以没必要定义两个不同的Function实例,况且,this对象可以把函数与对象的绑定推迟到运行时


每个函数都会创建一个prototype属性,这个属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。实例上,这个对象就是通过调用构造函数创建的对象的原型,使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。原来在构造函数中直接赋给对象实例的值,可以直接赋值给它们的原型

无论何时,只要创建一个函数,就会按照特定的规则为这个函数创建一个prototype属性指向原型对象,默认情况下,所有原型对象自动获得一个名为constructor的属性,指回与之关联的构造函数。

在自定义构造函数时,原型对象默认只会获得constructor属性,其他的所有方法都继承自Object,每次调用构造函数创建一个新实例,这个实例的内部[[Prototype]]指针就会被赋值为构造函数的原型对象。脚本中没有访问这个[[Prototype]]的标准方式,一些浏览器会在每个对象上暴露__proto__属性,通过这个属性可以访问对象的原型。

实例与构造函数原型之间有直接的联系,但实例与构造函数之间没有

虽然不是所有实现都对外暴露了[[Prototype]],但可以使用isPrototypeOf()方法确定两个对象之间的关系,isPrototypeOf()会在传入参数的[[Prototype]]指向调用它的对象时返回true

Object有一个方法叫Object.getPrototype(),返回参数的内部特性[[Prototype]]的值

Object.setPrototypeOf()可以向实例的私有特性[[Prototype]]写入一个新值,这样就可以重写一个对象的原型继承关系,但是会影响代码性能

Object.create()可以创建一个新对象,同时为其指定原型

原型层级

在通过对象访问属性时,会按照这个属性的名称开始搜索,搜索开始于对象实例本身,如果在这个实例上发现了给定的名称,则返回该名称对应的值,如果没有找到这个属性,则搜索会沿着指针进入原型对象,然后在原型对象上找到属性后,再返回对应的值,这就是原型用于在多个对象实例间共享属性和方法的原理

虽然可以通过实例读取原型对象上的值,但不能通过实例重写这些值,如果在实例上添加了一个原型对象中同名的属性,那就会在实例上创建这个属性,这个属性会遮住原型对象上的属性。

使用delete操作符可以删除实例上的属性

hasOwnProperty()方法用于确定某个属性是在实例上还是在原型对象上,这个方法是继承自Object的,会在属性存在于调用它的对象实例上时返回true

原型和in操作符

有两种方式使用in操作符:单独使用和在for-in循环中使用

在单独使用时,in操作符会在可以通过对象访问指定属性时返回true,无论该属性在实例上还是原型上。

如果要确定某个属性是否在原型上,可以同时使用hasOwnProperty()和in操作符

在for-in循环中使用in操作符时,可以通过对象访问且可以被枚举的属性都会返回,包括实例和原型属性

要获得对象上所有可枚举的实例属性,可以使用Object.keys()方法,这个方法接收一个对象作为参数,返回包含该对象所有可枚举属性名称的字符串数组

如果想列出所有实例属性,无论是否可以枚举,都可以使用Object.getOwnPropertyNames()

Object.getOwnPropertySymbols()方法针对符号

属性枚举顺序

for-in循环和Object.keys()的枚举顺序是不确定的

Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()和Object.assign()的枚举顺序是确定的,先以升序枚举数值键,然后以插入顺序枚举字符串和符号键,在对象字面量中定义的键以它们逗号分隔的顺序插入


Object.values()和Object.entries()将对象内容转换为序列化的,可迭代的格式,它们接收一个对象,返回它们内容的数组。Object.values()返回对象值的数组,Object.entries()返回键值对的数组,非字符串属性会被转换为字符串输出,这两个方法执行对象的浅复制,符号属性会被忽略

原型上搜索值是动态的,所以即使实例在修改原型之前已经存在,任何时候对原型对象的修改也会在实例上反映出来

实例的[[Prototype]]指针是在调用构造函数时自动赋值的,这个指针即使把原型修改为不同的对象也不会变,重写整个原型会切断最初原型与构造函数的联系,但实例引用的仍然是最初的原型

重写构造函数上的原型之后再创建的实例才会引用新的原型

通过原生对象的原型可以取得所有默认方法的引用,也可以给原生类型的实例定义新的方法。可以像修改自定义对象原型一样修改原生对象原型,因此随时可以添加方法

原型模式弱化了向构造函数传递初始化参数的能力,会导致所有实例默认都取得相同的属性值,原型的最主要问题是它的共享特性

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

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

相关文章

高通camx hal进程dump日志分析三:Pipeline DumpDebugInfo原理分析

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、问题背景 二、DumpDebugInfo原理 2.1:我们分析下代码 2.2 :Pipeline Dump debug info 2.3 :dump Metadata Pending Node信息 2.4 :Dump Metadata Pool Debug信息 2.5 :No…

【数据结构】_二叉树基础OJ

目录 1. 单值二叉树 1.1 题目链接与描述 1.2 解题思路 1.3 程序 2. 相同的树 2.1 题目链接与描述 2.2 解题思路 2.3 程序 3. 对称二叉树 3.1 题目链接与描述 3.2 解题思路 3.3 程序 1. 单值二叉树 1.1 题目链接与描述 题目链接: 965. 单值二叉树 - 力…

软件工程画图题

目录 1.大纲 2.数据流图 3.程序流图 4.流图 5.ER图 6.层次图 7.结构图 8.盒图 9.状态转换图 10.类图 11.用例图 12.活动图 13.判定表和判定树 14.基本路径测试过程(白盒测试) 15.等价类划分(黑盒测试) 1.大纲 (1).数据流图 (2).程序流图 (3).流图 (4).ER图…

H7-TOOL自制Flash读写保护算法系列,为华大电子CIU32F003制作使能和解除算法,支持在线烧录和脱机烧录使用2025-06-20

说明: 很多IC厂家仅发布了内部Flash算法文件,并没有提供读写保护算法文件,也就是选项字节算法文件,需要我们制作。 实际上当前已经发布的TOOL版本,已经自制很多了,比如已经支持的兆易创新大部分型号&…

go channel用法

介绍 channel 在 Go 中是一种专门用来在 goroutine 之间传递数据的类型安全的管道。 你可以把它理解成: 多个 goroutine 之间的**“传话筒”**,谁往通道里塞东西,另一个 goroutine 就能接收到。 Go 语言采用 CSP(Communicatin…

openLayers切换基于高德、天地图切换矢量、影像、地形图层

1、需要先加载好地图,具体点此链接 openLayers添加天地图WMTS、XYZ瓦片服务图层、高德地图XYZ瓦片服务图层-CSDN博客文章浏览阅读31次。本文介绍了基于OpenLayers的地图交互功能实现,主要包括以下内容: 地图初始化:支持天地图XYZ…

springMVC-15 异常处理

异常处理-基本介绍 基本介绍 1.Spring MVC通过HandlerExceptionResolver处理程序的异常,包括Handler映射、数据绑定以及目标方法执行时发生的异常。 2.主要处理Handler中用ExceptionHandler注解定义的方法。 3.ExceptionHandlerMethodResolver内部若找不到Excepti…

视频汇聚EasyCVR平台v3.7.2发布:新增全局搜索、播放器默认解码方式等4大功能

EasyCVR视频汇聚平台带着全新的v3.7.2版本重磅登场!此次升级,绝非简单的功能堆砌,而是从用户体验、操作效率以及系统性能等多维度进行的深度优化与革新,旨在为大家带来更加强大、稳定且高效的视频监控管理体验。 一、全局功能搜索…

三、kubectl使用详解

三、kubectl使用详解 文章目录 三、kubectl使用详解1、常用基础命令1.1 Kubectl命令格式1.2 查询一个资源1.3 创建一个资源1.4 修改一个资源1.5 删除一个资源1.6 其他 2、K8s隔离机制Namespace(命名空间作用及使用)2.1 什么是命名空间2.2 命名空间主要作…

JVM内存模型详解

JVM内存模型详解 Java虚拟机(JVM)内存模型是理解Java程序运行机制的核心,它定义了程序运行时数据的组织方式和访问规则。与Java内存模型(JMM)关注并发不同,JVM内存模型主要描述运行时数据区的结构和功能。 一、JVM内存模型概述 JVM内存模型将运行时数…

《对话式 AI 白皮书》共创者招募

在 AI Agent 技术不断演变的当下,共创一本不断演变的对话式 AI 白皮书,共同探索人机对话的新纪元。无论你是开发者、技术专家、生态伙伴还是创业者,都期待你的加入。 项目地址:https://github.com/RTE-Dev/book_era_convoai/ 在…

Flux功能介绍,完整使用示例,与Mono对比

以下是关于Reactor框架中Flux与Mono的功能介绍、使用示例及对比分析: Flux功能介绍 核心定义 Flux是Reactor库中的核心接口,表示一个异步的、包含零到多个元素的序列(类似流式数据处理)[3][4][7]。它可以处理无限长度的数据流&am…

Git使用基本指南

一、Git 基础配置 首先需要配置用户信息,让 Git 知道你是谁: git config --global user.name "你的名字" git config --global user.email "你的邮箱example.com" 如果需要查看配置信息,可以使用: git co…

【入门】【例17.3】 内功逼毒

| 时间限制:C/C 1000MS,其他语言 2000MS 内存限制:C/C 64MB,其他语言 128MB 难度:中等 分数:100 OI排行榜得分:12(0.1分数2难度) 出题人:root | 描述 黄蓉中了毒,在 t 时…

苹果芯片macOS安装版Homebrew(亲测)

在Linux服务器上安装一个软件常用yum,apt、dnf命令,同样macOS可以使用brew命令来安装软件。 brew会自动帮你下载、解压、安装和配置,更重要的是:它还会自动处理好软件之间的依赖关系,它将所有软件都安装在独立的统一目…

uniapp+vue3做小程序,获取容器高度

小程序获能用createSelectorQuery,如果是子组件,后面可以额外加一个参数in来指定获取dom的范围。小程序里面可以直接.in(this),但是vue3没有this了,那就只能通过getCurrentInstance去获取当前实例代替this ,注意这里需…

【网工】华为配置专题进阶篇①

目录 ■浮动路由和BFD配置 ▲浮动路由 基本配置示例 ▲BFD ▲验证命令 ▲测试连通性 ■路由综合实验RIP OSPF BGP ■浮动路由和BFD配置 ▲浮动路由 浮动路由:设置preference 浮动路由是一种备份路由机制,当主路由失效时,浮动路由会…

DeepLegal AI:智能法律文档审查与合规助手+MVP

1. 商业价值与市场机会 DeepLegal AI旨在革新法律行业中耗时且资源密集型的文档审查和合规流程。该应用将利用DeepSeek先进的语言模型能力,为律师事务所、企业法务部门和合规团队提供一个高效、准确且经济的解决方案。 市场机会: 法律科技市场正经历爆…

使用 Rust 编写简单计算器

在编程语言的世界中,Rust 以其安全性和高性能而闻名。今天,我们将通过一个简单的项目来探索 Rust 的魅力 —— 编写一个简单的命令行计算器。这个计算器将支持基本的算术运算(加、减、乘、除),并且可以通过用户输入进行…

清华大学:《AI赋能教育 :高考志愿填报工具使用指南》下载

志愿填报的认知革命已经到来 “分数出来了,但不知道能上什么学校……” “喜欢这个专业,但不知道就业前景怎么样?” “到底是选热门专业还是选兴趣爱好?” 这些让百万家庭彻夜难眠的问题,你是否正在经历? …