创建对象

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

1.工厂模式 

工厂模式是一种众所周知的设计模式,广泛应用于软件工程领域,用于抽象创建特定对象的过程 

function createPerson(name,age){let o=new Object(); o.name=name; o.age=age; o.sayName=function(){console.log(this.name);};return o;}let person1=createPerson('a',18);let person2=createPerson('b',19)

可以根据用不同的参数多次调用这个函数,每次都会返回2个属性和1个方法的对象,这种工厂模式虽然可以解决多个类似对象的问题,但没有解决对象标识问题(即新创建的对象是什么类型),每次创建对象的时候方法都会创建  

2.构造函数模式 

//第一种写法  
function Person(name,age){this.name=name; this.age=age; this.sayName=function(){console.log(this.name) };
}let person1=new Person("Nicholas",29);
let person2=new Person('b',27)//第二种写法 
let Person =function(name,age,job){this.name=name; this.age=age; this.sayName=function(){console.log(this.name) };
}//不传参数
function Person(){this.name="JaKe"; this.sayName=function(){console.log(this.name) };
}
let person1=new Person(); 
let Person2=new Person; 

Person()构造函数代替了createPerson()工厂函数,实际上Person()内部的代码跟createPerson()基本是一样的,只是有如下区别 

  • 没有显式地创建对象
  • 属性和方法直接复制给了this 
  • 没有return 

另外要注意按照惯例构造函数名称的首字母要大写,非构造函数则以小写字母开头,有助于区分构造函数和普通函数 

1.要创建Person的实例,应使用new操作符,使用new操作符会执行如下操作
  1. 在内存中创建一个新对象
  2. 这个新对象内部的[[prototype]]特性被赋值为构造函数的prototype属性 
  3. 构造函数内部的this被赋值为这个新对象(即this指向新对象)
  4. 执行构造函数内部的代码(给新对象添加属性)
  5. 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象 

上个例子,person1和person2分别保存着Person的不同实例,这两个对象都有一个construcotr属性指向Person,如下所示 

conosle.log(person1.constructor==Person); //true  

console.log(person2.constructor==Person); //true 

instanceof操作符  用于判断一个对象是否是某个构造函数的实例 

console.log(person1 instanceof Object) //true   因为Person1是通过构造函数Person创建的,而Person.prototype最终继承自object.prototype 换句话说,所有对象的原型链最终都会指向Object.prototype 


console.log(person1 instanceof Person) 

2.1构造函数也是函数 

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

//作为构造函数

let person=new Person('a',17)

person.sayName(); 


//作为函数调用

Person("Greg",27); //添加到window对象 

window.sayName(); //"Greg"

//在领一个对象的作用域中调用

let o = new Object( ); 

Person.call(o,'Kristen',25)

o.sayName(); //"Kristen" 

2.2  构造函数的问题

构造函数虽然有用,但也不是没有问题,构造函数的主要问题在于,其定义的方法会在每个实例上都创建一遍,因此对前面的例子而言,person1和person2都有名为sayName()的方法,但这两个方法不是同一个Funtion实例,我们知道,js中的函数是对象,因此每次定义函数时,都会初始化一个对象

conosle.log(person1.sayName==person2.sayName); //false 

虽然可以把函数转移到构造函数外部,但是这样会搞乱全局作用域,这个新问题可以通过原型模式来解决 

3. 原型模式 (请看下面这篇文章)

js对象原型,原型链-CSDN博客

4.属性枚举顺序

for-in循环,Object.keys(),Object.getOwnPropertyNames(),Object.getOwnProperty-Symbols()以及Object.assign()在属性枚举顺序方面有很大区别,for-in循环和Object.keys()的枚举顺序是不确定的取决于js引擎,可能因浏览器而异 

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

let k1 = Symbol('k1'),k2 = Symbol('k2');let o = {1: 1,first: 'first',[k1]: 'sym2',second: 'second',0: 0
};o[k2] = 'sym2';
o[3] = 3;
o.third = 'third';
o[2] = 2;console.log(Object.getOwnPropertyNames(o));
// ["0", "1", "2", "3", "first", "second", "third"]console.log(Object.getOwnPropertySymbols(o));
// [Symbol(k1), Symbol(k2)]

5. 对象迭代 

1.Object.values() //返回对象值的数组
2. Object.entries() //返回健/值对的数组 
const o = {foo: 'bar',baz: 1,qux: {}
};console.log(Object.values(o));
// ["bar", 1, {}]console.log(Object.entries((o)));
// [["foo", "bar"], ["baz", 1], ["qux", {}]]注意: 非字符串属性会被转换为字符串输出,另外,这两个方法执行对象的浅复制: const o = {qux: {}
};console.log(Object.values(o)[0] === o.qux);
//true console.log(Object.entries(o)[0][1]=== o.qux); 
//true 符号属性会被忽略: 
const sym=Symbol(); 
const o={[sym]: 'foo'
}; 
console.log(Object.values(o));
// []
console.log(Object.entries((o)));
// []

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

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

相关文章

深度理解指针(2)

🎁个人主页:工藤新一 🔍系列专栏:C面向对象(类和对象篇) 🌟心中的天空之城,终会照亮我前方的路 🎉欢迎大家点赞👍评论📝收藏⭐文章 深入理解指…

数据科学和机器学习的“看家兵器”——pandas模块 之一

目录 pandas 模块介绍 4.1 pandas 数据结构 一、课程目标 二、Series 对象介绍 三、DataFrame 对象介绍 四、Series 和 DataFrame 在具体应用中的注意事项 (一)Series 注意事项 (二)DataFrame 注意事项 五、实战案例 案例 1:学生成绩分析 案例 2:销售数据分析 案例 3:股…

STM32CubeMX HAL库 串口的使用

1.配置 2.开启中断后,生成代码 3.串口的接收 1).开启空闲中断接收 __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE); // 关键步骤:启用空闲中断 2). 启动接收 调用 HAL_UARTEx_ReceiveToIdle_IT 启动异步接收,可以使用…

IIS服务器URL重写配置完整教程

1.下载URL Rewrite Module 2.1 https://www.iis.net/downloads/microsoft/url-rewrite https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_zh-CN.msi 2.安装

vite+vue建立前端工程

​ 参考 开始 | Vite 官方中文文档 VUE教程地址 https://cn.vuejs.org/tutorial/#step-1 第一个工程 https://blog.csdn.net/qq_35221977/article/details/137171497 脚本 chcp 65001 echo 建立vite工程 set PRO_NAMEmy-vue-appif not exist %PRO_NAME% (call npm i…

负进制转换

当一个数的基数是负数时,将这个数转换为负进制数时,大体思路和正数的情况一样,但是因为基数是负数,所以计算出来的余数就有可能是负数所以,需要在余数是负数时:将余数 基数的绝对值,商 1。 代…

K8S已经成为了Ai应用运行的平台工具

AI应用与K8s的深度融合:加速云原生时代的智能运维与业务创新 摘要: 随着人工智能(AI)技术的飞速发展,Kubernetes(K8s)作为容器编排领域的领军者,正逐步成为承载AI应用的核心基础设施…

NVMe简介1

它分为两部分,这里是第一部分。 NVM Express(NVMe)是一种高性能、可扩展的接口协议,用于通过PCI express(PCIe)总线,实现主机软件与NVM设备之间的通信。目前,由于NVMe SSD相比于SATA…

微服务商城(1)开篇、服务划分

参考:https://mp.weixin.qq.com/s?__bizMzg2ODU1MTI0OA&mid2247485597&idx1&sn7e85894b7847cc50df51d66092792453&scene21#wechat_redirect 为什么选择go-zero go-zero 为我们提供了许多高并发场景下的实用工具,比如为了降低接口耗时…

《隐私计算:数据安全与隐私保护的新希望》

一、引言 在数字化时代,数据已成为企业和组织的核心资产。然而,数据的收集、存储和使用过程中面临着诸多隐私和安全挑战。隐私计算作为一种新兴技术,旨在解决数据隐私保护和数据共享之间的矛盾。本文将深入探讨隐私计算的基本概念、技术原理、…

MySQL 学习(九)bin log 与 redo log 的区别有哪些,为什么快速恢复使用 redo log 而不用 bin log?

目录 一、bin log 与 redo log 的区别1)实现方式不同:2)日志内容不同:3)记录方式不同:4)使用场合不同: 二、为什么快速恢复使用 redo log 而不用 bin log? 面试题&#x…

用Array.from实现创建一个1-100的数组

一、代码实现 let arr Array.from({length: 100}, (_, i) > i 1); 二、代码分析 1、Array.from(arrayLike, mapFn) (1)arrayLike 类数组对象(如 { length: 100 })本身没有索引属性(如 0: undefined, 1: undefi…

javaScript简单版

简介 JavaScript(简称:JS)是一门跨平台、面向对象的脚本语言,是用来控制网页行为,实现页面的交互效果。 JavaScript和Java是完全不同的语言,不论是概念还是设计。但是基础语法类似。 组成: ECMAScript:规定了JS基础语法核心知…

Python刷题练习

文章目录 1.寻找相同字串2.密钥格式化3.五键键盘的输出4.单词重量5.输出指定字母在字符串的中的索引6.污染水域7.九宫格按键输入8.任务最优调度9.高效的任务规划 1.寻找相同字串 题目描述: 给你两个字符串t和p,要求从t中找到一个和p相同的连续子串,并输…

MATLAB实现振幅调制(AM调制信号)

AM调制是通信专业非常重要的一个知识点。今天我们使用MATLAB编程实现AM调制。 我们实现输入一个载波信号的频率与调制信号的频率后,再输入调幅度,得到已调信号的波形与包络信号的波形,再使用FFT算法分析出已调信号的频谱图。 源代码&#x…

JJJ:linux ida

文章目录 1.总结2.各类函数2.1 分配一个仓库2.2 销毁仓库2.3 从仓库里面分配一个整数id2.4 将上面分配的整数id从仓库里面删除2.5 在指定范围内分配一个id 1.总结 ida使用起来很简单,就是先分配一个仓库一样的实例,再从这个仓库里面分配一个独一无二的整…

FastByteArrayOutputStream和ByteArrayInputStream有什么区别

FastByteArrayOutputStream 和 ByteArrayInputStream 是两种完全不同的 Java I/O 类,它们的主要区别体现在 设计目的 和 使用场景 上。以下是详细对比: 1. 核心区别总结 特性FastByteArrayOutputStream (Spring框架)ByteArrayInputStream (JDK原生)所属…

docker-compose——安装redis

文章目录 一、编写docker-compose.yaml文件二、编写redis.conf文件三、启动docker-compose 一、编写docker-compose.yaml文件 version: 3.3 services:redis:image: redis:latestcontainer_name: redisrestart: alwaysports:- 6379:6379volumes:- ./redis/data:/data- ./redis/…

东芝推出新的SCiB模块,散热性能加倍,适用于电动公交车、电动船舶和固定应用

东京—东芝公司推出了一种新的SCiB模块,这是一种专为电动汽车、电动船舶和固定应用而设计的锂离子电池。新产品采用铝制底板,散热量约为当前模块的两倍。它将于2025年4月中旬在日本和全球上市。 锂离子电池的使用越来越多,而且越来越多样化&a…

【进程控制二】进程替换和bash解释器

【进程控制二】进程替换 1.exec系列接口2.execl系列2.1execl接口2.2execlp接口2.3execle 3.execv系列3.1execv3.2总结 4.实现一个bash解释器4.1内建命令 通过fork创建的子进程,会继承父进程的代码和数据,因此本质上还是在执行父进程的代码 进程替换可以将…