手写new

手写new

  • new是什么
  • 执行new会发生什么
  • 实现new

new是什么

new 操作符是可以创建一个用户定义的对象的实例或具有构造函数的内置对象的实例

function Car (make, model, year) {this.make = makethis.model = modelthis.year = year
}
Car.prototype.running = function () {return `${this.year}${this.make} 公司造的 ${this.model} 牌汽车,开动起来`
}
const car = new Car('长城', '坦克300', '2022')
console.log(car)

打印出的Car实例
在这里插入图片描述
从上图可以看到,实例里面有以下内容:

  1. 三个属性:make,model,year并且已经赋值
  2. 原型上有一个running方法,constructor为Car

思考一下,如果构造函数返回了一个新对象或者返回其它基本类型的数据,结果还一样吗?
修改上面的例子

function Car (make, model, year) {this.make = makethis.model = modelthis.year = yearreturn {info: `${this.year}${this.make} 公司造的 ${this.model}`}}Car.prototype.running = function () {return `${this.year}${this.make} 公司造的 ${this.model} 牌汽车,开动起来`}const car = new Car('长城', '坦克300', '2022')console.log(car)

打印出的Car实例
在这里插入图片描述
从上图中可以看出:

  1. 实例是个普通的Object对象,这个对象就是执行构造函数return时的结果
  2. 实例的原型是Object,且其constructor不再是Car,而是Object

继续修改上面的例子,使其构造函数返回一个基本类型的数据

function Car (make, model, year) {this.make = makethis.model = modelthis.year = yearreturn '测试'}Car.prototype.running = function () {return `${this.year}${this.make} 公司造的 ${this.model} 牌汽车,开动起来`}const car = new Car('长城', '坦克300', '2022')console.log(car)

打印出的Car实例
在这里插入图片描述
从上图中可以看出和没有写return是一样的,返回的都是新创新的Car实例

执行new会发生什么

根据上面的例子内容,可以总结出使用new会进行如下的操作:

  1. 创建一个空的简单js对象(即{})
  2. 为该对象设置原型,将对象的原型(proto)设置为构造函数的protortype对象
  3. 将函数的this指向这个对象,执行构造函数,并将参数进行赋值。
  4. 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

实现new

知道了new的执行过程,手写一个new,就变得很容易了

  1. 方法1
function newApply (Fun, ...rest) {// 步骤一 创建一个空对象const newObj = {} // 步骤二 新创建的对象上面添加属性 __proto__, 并将该属性链接至构造函数的原型对象newObj.__proto__ = Fun.prototype // 步骤三 新创建的对象作为 this 的上下文const result = Fun.apply(newObj, rest)// 步骤四 如果执行结果有返回值并且是一个对象,就返回执行的结果,否者返回 this 也就是新创建的对象 newObjreturn result instanceof Object ? result : newObj
}

测试

const car = new Car('长城', '坦克300', '2022')
console.log('car', car)
const newApplyCar = newApply(Car, '长城', '坦克300', '2022')
console.log('newApplyCar', newApplyCar)
  1. 方法2
function newCall (Fun, ...rest) {// 步骤一 基于 Fun 的原型创建一个新的对象。不管怎么样都不建议修改对象的原型,这可能会极大的影响性能。因此原型赋值这块代码可以优化下,直接使用Object.create,在创建的时候就设置好原型const newObj = Object.create(Fun.prototype)// 步骤二 新创建的对象作为 this 的上下文const result = Fun.call(newObj, ...rest)// 步骤三 如果执行结果有返回值并且是一个对象,就返回执行的结果,否者返回 this 也就是新创建的对象 newObjreturn result instanceof Object ? result : newObj}

测试

const car = new Car('长城', '坦克300', '2022')
console.log('car', car)
const newApplyCar = newCall(Car, '长城', '坦克300', '2022')
console.log('newApplyCar', newApplyCar)

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

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

相关文章

[Linux]添加sudoers

之前我们讲过sudo这个命令,它可以让我们普通用户进行短暂的提权,上回我们讲完了vim 本篇是个短篇,目的就是让我们之后的学习中可以使用sudo命令。 首先我们先登录root用户 ls /etc/sudoer 我们需要改的就是上面的这个文件 vim /etc/sudoers 我们用vim打开 把光标移动到这…

微信小程序实现和AI语音对话功能

1.效果 微信小程序与AI语音对话 2.效果主要实现技术 ①AI语音合成(阿里云平台) ②微信小程序同声传译功能 ③本功能是用原生微信小程序实现的(可自行转成uniapp代码) 3.同声传译 进入微信服务市场,搜索同声传译就能找…

python关于excel常用函数(pandas篇)

iterrows函数: Pandas的基础数据结构可以分为两种:DataFrame和Series。不同于Series的是,Dataframe不仅有行索引还有列索引 。df.iterrows( )函数:可以返回所有的行索引,以及该行的所有内容。 pd.read_excel&#xf…

小型数控车床对现代制造业的影响

小型数控车床作为现代制造业的重要生产工具,集成了计算机控制、精密机械、电子技术和自动化技术,为各种复杂零件的加工,在生产效率和精度上带来了显著提升,它是制造业中不可或缺的基础装备,在金属切削加工领域发挥着关…

车间数据采集网关的工作原理和应用场景-天拓四方

在智能制造日益盛行的今天,车间数据采集作为整个生产流程中的关键环节,其重要性愈发凸显。数据采集网关作为这一环节的核心设备,扮演着承上启下的重要角色。本文旨在深入探讨车间数据采集网关的工作原理和应用场景。 一、数据采集网关的工作…

Java基础知识——继承

目录 一、什么是继承 二、类的继承格式 三、继承的特点 四、继承的类型 五、继承的关键字 六、为什么使用继承 一、什么是继承 继承是面向对象编程(OOP)的四大基本原则之一,它允许我们创建一个新类,继承并扩展现有类的属性和…

【HarmonyOS学习】Calendar Kit日历管理

简介 Calendar Kit提供日历与日程管理能力,包括日历的获取和日程的创建能力。 Calendar Kit为用户提供了一系列接口来获取日历账户,并使用特定的接口向日历账户中写入日程。 如果写入的日程带有提醒时间则系统会在时间到达时向用户发送提醒。 约束点…

eclipse 新建类class文件增加copyright版权信息

1、Window -> Preferences 2、输入code,找到code templates Java > Code Style > Code Templates 比如进行如何的设置: 3、新增类文件,会自动增加版权:

2024.7.12单片机PWM

遇到了一个光标变成下划线的问题: Keil5光标变下划线,变回来的方法_keil5光标是下划线-CSDN博客 这里是用了输入捕获(IC:input capture),输出比较(OC:Output Compare)区别 学到这…

解析DDD开发框架Axon

在微服务架构盛行的当下,领域驱动设计(DDD)也得到了崭新的发展。在DDD中包含了聚合、领域事件等核心概念,也需要引入CQRS、事件溯源等架构模式。对于开发人员而言,如何简单而高效的实现这些核心概念和架构模式是一大痛…

集群节点状态异常的解决方式

文章目录 集群节点状态异常的解决方式问题概述解决方式1.关闭所有服务2.对所有集群删除Hadoop相关文件2.1 删除Hadoop系统运行时创建的临时数据和文件2.2 删除Hadoop的数据文件 3.重新对Hadoop节点进行初始化和启用4.重启服务,检查节点状态 集群节点状态异常的解决方…

软件测试工作流程

1、目的 有效的保证软件质量;有效的制定不同测试类型(软件系统测试、音频主观性测试、专项测试、自动化测试、性能测试、用户体验测试)的软件测试计划;按照计划进行测试,发现软件中存在的问题;对软件中已经解决的问题进行有效的验证;判定测试过程和问题验证的有效性。2、…

PostgreSQL(二十一)clog的作用与管理

一、CLOG的概念及作用 1、基础概念 (1)CLOG:记录事务号的状态,可以用其判断行的可见性。每个事务状态占用两个bit位。 tip:事务的状态有4种:IN_PROGRESS,COMMITTED,ABORTED和SUB_…

如何应对AI发展下的伦理挑战

目录 1.概述 2.构建可靠的AI隐私保护机制 2.1. 最小化数据收集 2.2. 数据去标识化 2.3. 加密技术 2.4. 分布式学习和边缘计算 2.5. 强化用户控制权 2.6. 独立审计和合规性检查 2.7. 持续教育和培训 2.8.小结 3.确保AI算法的公正性和透明度 3.1.增强AI决策透明度的方…

第一百五十九节 Java IO教程 - Java输入流、文件输入流、缓冲输入流、推回输入流

Java IO教程 - Java输入流 抽象基本组件是InputStream类。 InputStream|--FileInputStream |--ByteArrayInputStream |--PipedInputStream|--FilterInputStream|--BufferedInputStream |--PushbackInputStream |--DataInputStream |--ObjectInputStream我们有FileInputStream&…

【C++】——类和对象(中)

文章目录 类的默认成员函数构造函数析构函数拷贝构造函数赋值运算符重载运算符重载 const成员函数 类的默认成员函数 在C中,类(class)可以拥有多种成员函数,其中一些成员函数在类定义中没有显式声明时,编译器会隐式地…

Windows上LabVIEW编译生成可执行程序

LabVIEW项目浏览器(Project Explorer)中的"Build Specifications"就是用来配置项目发布方法的。在"Build Specifications"右键菜单中选取"New",可以看到程序有几种不同的发布方法:Application(EXE)、Installer、.Net Inte…

C++第七弹 -- C/C++内存管理

目录 前言一. C/C内存分布二. C语言中动态内存管理方式三. C中动态内存管理四. operator new与operator delete函数五. new和delete的实现原理1.内置类型2. 自定义类型 六. 定位new表达式(placement-new)七. 常见面试题总结 前言 在C/C编程中,内存管理是至关重要的…

超详细Midjourney国际版注册使用全流程

众所周知,目前Midjourney AI绘画的国内版本有很多种,甚至微信、浏览器插件等都有,眼花缭乱,使用门槛低,无需特殊网络手段即可访问使用。 不过,根据一些用户的反馈,尽管国内的那些版本在注册和充…

软件测试——测试用例

工作职责: 1.负责产品系统测试,包括功能测试、性能测试、稳定性测试、用户场景测试、可靠性测试等。 2.负责测试相关文档的编写,包括测试计划、测试用例、测试报告等。 3.负责自动化测试框架、用例的维护。 岗位要求: 1.熟练…