手写new

手写new

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

new是什么

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

function Car (make, model, year) {
    this.make = make
    this.model = model
    this.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 = make
    this.model = model
    this.year = year
    return {
      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 = make
    this.model = model
    this.year = year
    return '测试'
  }

  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 也就是新创建的对象 newObj
    return 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 也就是新创建的对象 newObj
    return 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.mfbz.cn/a/801379.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

R语言极值分析:GEV与GPD模型与MCMC的海洋观测数据极值模拟可视化研究

全文链接:https://tecdat.cn/?p37007 原文出处:拓端数据部落公众号 在海洋科学领域,极端天气和海洋事件如极端海浪、风暴潮和海啸等,对沿海社区、基础设施及生态环境构成了重大威胁。准确预测和评估这些极端事件的强度和频率&a…

Golang中读写锁的底层实现

目录 Sync.RWMutex 背景与机制 接口简单介绍 sync.RWMutex 数据结构 读锁流程 RLock RUnlock RWMutex.rUnlockSlow 写锁流程 Lock Unlock Sync.RWMutex 背景与机制 从逻辑上,可以把 RWMutex 理解为一把读锁加一把写锁; 写锁具有严格的排他性&…

Qt程序图标更改以及程序打包

Qt程序图标更改以及程序打包 1 windows1.1 cmake1.1.1 修改.exe程序图标1.1.2 修改显示页面左上角图标 1.2 qmake1.2.1 修改.exe程序图标1.2.2 修改显示页面左上角图标 2 程序打包2.1 MinGW2.2 Visual Studio 3 参考链接 1 windows 1.1 cmake 1.1.1 修改.exe程序图标 获得一个…

【Linux】进程控制的详细介绍

前言 在此之前,我们学过进程的概念,进程的状态,进程地址空间等一系列进程相关的问题。本章我们继续学习进程,我们要来学习一下进程的控制,关于进程等待,等问题。 目录 1.再次认识Fork函数1.1 fork()之后操…

搜集日志。

logstash 负责: 接收数据 input — 解析过滤并转换数据 filter(此插件可选) — 输出数据 output input — decode — filter — encode — output elasticsearch 查询和保存数据 Elasticsearch 去中心化集群 Data node 消耗大量 CPU、内存和 I/O 资源 分担一部分…

数据结构进阶:使用链表实现栈和队列详解与示例(C, C#, C++)

文章目录 1、 栈与队列简介栈(Stack)队列(Queue) 2、使用链表实现栈C语言实现C#语言实现C语言实现 3、使用链表实现队列C语言实现C#语言实现C语言实现 4、链表实现栈和队列的性能分析时间复杂度空间复杂度性能特点与其他实现的比较…

启动yarn后,其他节点没有NodeManager

写在前面: 这个问题虽然折磨了我两天,但是原因特别蠢,可能与各位不一定一样,我是因为ResourceManager的节点的"/etc/hadoop/workers"文件没有配置好(没有配hadoop102和hadoop104),但排…

MySQL日期和时间相关函数

目录 1. 获取当前时间和日期 2. 获取当前日期 3. 获取当前时间 4. 获取单独的年/月/日/时/分/秒 5. 添加时间间隔 date_add ( ) 6. 格式化日期 date_format ( ) 7. 字符串转日期 str_to_date () 8. 第几天 dayofxx 9. 当月最后一天 last_day ( ) 10. 日期差 datedif…

Java中的线程同步

为什么要实现线程同步 线程的同步是为了保证多个线程按照特定的顺序、协调地访问共享资源,避免数据不一致和竞争条件等问题。 线程同步的方式 1.synchronized关键字 (1)同步方法 public synchronized void save(){} 注: syn…

网络编程+文件上传操作的理解

前言: 概述:在网络通信协议下,不同计算机上运行的程序,进行数据传输 比如:通信,视频通话,网游,邮件等 只要是计算机之间通过网络进行数据传输,就有网络编程的存在 (下面单纯是在Java基础中了解了一下网络编程,感觉理…

如何保证数据库和redis的数据一致性

1、简介 在客户端请求数据时,如果能在缓存中命中数据,那就查询缓存,不用在去查询数据库,从而减轻数据库的压力,提高服务器的性能。 2、问题如何保证两者的一致性 先更新数据库在删除缓存 难点:如何保证…

Classifier-Free Guidance (CFG) Scale in Stable Diffusion

1.Classifier-Free Guidance Scale in Stable Diffusion 笔记来源: 1.How does Stable Diffusion work? 2.Classifier-Free Diffusion Guidance 3.Guide to Stable Diffusion CFG scale (guidance scale) parameter 1.1 Classifier Guidance Scale 分类器引导是…

vite配置环境变量和使用,配置正确后import.meta.env.VITE_APP_BASE_URL编译报错的解决方法

一、配置: 1.新增四个环境文件 .env.development .env.test .env.production .env.pre 内容为不同环境的不同参数变量必须以VITE_APP开头,如: #接口地址 VITE_APP_BASE_URL"¥¥¥¥&#xff…

嵌入式人工智能(6-树莓派4B按键输入控制LED)

1、按键 按键的原理都是一样,通过按键开关的按下导通,抬起断开的情况,GPIO引脚来检测其是否有电流流入。GPIO有input()方法,对于GPIO引脚检测电流,不能让其引脚悬空,否则引脚会受周边环境电磁干扰产生微弱…

获取欧洲时报中国板块前新闻数据(多线程版)

这里写目录标题 一.数据获取流程二.获取主页面数据并提取出文章url三.获取文章详情页的数据并提取整体代码展示 一.数据获取流程 我们首先通过抓包就能够找到我们所需数据的api 这里一共有五个参数其中只有第一个和第五个参数是变化的第一个参数就是第几页第五个是一个由时…

HCNA ICMP:因特网控制消息协议

ICMP:因特网控制消息协议 前言 Internet控制报文协议ICMP是网络层的一个重要协议。ICMP协议用来在网络设备间传递各种差错和控制信息,他对于手机各种网络信息、诊断和排除各种网络故障有至关重要的作用。使用基于ICMP的应用时,需要对ICMP的工…

中介者模式(行为型)

目录 一、前言 二、中介者模式 三、总结 一、前言 中介者模式(Mediator Pattern)是一种行为型设计模式,又成为调停者模式,用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地互相引用,从而使其耦合…

防火墙双机热备(接上一个NAT实验)

一、实验拓扑 二、实验需求 1、对现有网络进行改造升级,将当个防火墙组网改成双机热备的组网形式,做负载分担模式,游客区和DMZ区走FW3,生产区和办公区的流量走FW1 2、办公区上网用户限制流量不超过100M,其中销售部人员…

【深度学习】基于深度学习的模式识别基础

一 模式识别基础 “模式”指的是数据中具有某些相似特征或属性的事物或事件的集合。具体来说,模式可以是以下几种形式: 视觉模式 在图像或视频中,模式可以是某种形状、颜色组合或纹理。例如,人脸、文字字符、手写数字等都可以视…

【边缘计算网关教程】8.ModbusTCP采集存储Influxdb

前景回顾-【边缘计算网关教程】7.Modbus协议转MQTT协议-CSDN博客 需求概述 💡注:使用Influxdb数据库节点,需要插上micro sd卡才可以 本章节主要实现一个流程:EG8200每10秒采集一次Modbus TCP数据存入Influxdb数据库,并且每分钟…