手写new

news2024/11/15 12:09:10

手写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.coloradmin.cn/o/1928786.html

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

相关文章

Zynq系列FPGA实现SDI编解码转SFP光口传输(光端机),基于GTX高速接口,提供6套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案在Xilinx-Kintex7上的应用 3、详细设计方案设计原理框图输入Sensor之-->OV5640摄像头输入Sensor之-->HDMIVDMA图像缓存RGB转BT1120GTX 解串与串化SMPTE SD/HD/3G SDI IP核BT1120转RGBHDMI输…

实习随笔【iviews的Select实现‘与全部互斥’的多选】

在实习中,遇到了如下需求,要求如下: 上面提到了一个需求为,选择全部与选择一个或者多个互斥,我们来看一下如何解决 核心代码 监听value的变化,如果含有‘全部’,且数组长度>1,则删…

Redis面试问题一

Redis在面试中有很大的概率会问到,因此我们一定要学会回答此方面的问题。 Redis主要涉及到使用场景已经一些其他方面的问题。 下面是有可能涉及到的问题。 问题一:你最近的项目中那些场景用到了Redis呢? 需要结合简历项目上的业务进行具体…

Rust 通过 Deref trait 将智能指针当作常规引用处理

通过 Deref trait 将智能指针当作常规引用处理 实现 Deref trait 允许我们重载 解引用运算符(dereference operator)*(与乘法运算符或通配符相区别)。通过这种方式实现 Deref trait 的智能指针可以被当作常规引用来对待&#xff…

WPF+MvvmLight 项目入门完整教程(一)

WPF+MvvmLight入门完整教程一 创建项目MvvmLight框架安装完善整个项目的目录结构创建自定义的字体资源下载更新和使用字体资源创建项目 打开VS2022,点击创建新项目,选择**WPF应用(.NET Framework)** 创建一个名称为 CommonProject_DeskTop 的项目,如下图所示:MvvmLight框架…

SQL Server 2019安装详细教程(图文详解,非常靠谱)

Microsoft SQL Server 是一种关系数据库管理系统 (RDBMS)。 应用程序和工具连接到 SQL Server 实例或数据库,并使用 Transact-SQL (T-SQL) 进行通信。 SQL Server Management Studio (SSMS) 是一种集成环境,用于管理任何 SQL 基础结构。 使用 SSMS 访问、…

AutoGen实战AI Agent开发

最近,关于 AI 智能体或AI代理(AI Agent)的讨论很多。受这种炒作的影响,我阅读了一些资料,偶然发现了 AutoGen,这是一个构建 AI 代理的很棒的库。但 AI 代理到底是什么?为什么它们很重要&#xf…

移动UI:表单美观易操作的十大准则,非常实用。

移动端表单设计需要遵循一些原则,以确保美观和易操作: 1.简洁明了: 在移动端表单设计中,要尽量简化内容,避免过多的文字和元素,保持简洁明了的布局,以便用户能够快速理解并填写表单。 2.响应式…

在 PostgreSQL 中如何优化涉及多个视图嵌套和函数调用的复杂查询?

🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会!📚领书:PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 中如何优化涉及多个视图嵌套和函数调用的复杂查询一、理解问题的本质二、优化的基本原则…

直播美颜工具开发教学:视频美颜SDK集成详解

本篇文章,笔者将详细介绍如何在直播应用中集成视频美颜SDK,让你的直播画面焕然一新。 一、什么是视频美颜SDK? 视频美颜SDK是一种软件开发工具包,提供了视频处理和图像增强功能。通过集成视频美颜SDK,开发者可以轻松…

【postgresql】角色(Role)

PostgreSQL 中,角色(Role)是一个重要的概念,用于管理数据库的访问权限和用户身份。角色可以被视为用户或组,具体取决于它们的配置方。 角色属性 角色可以具有多种属性: LOGIN:允许角色登录数据…

Apple Vision Pro 和其商业未来

机器人、人工智能相关领域 news/events (专栏目录) 本文目录 一、Vision Pro 生态系统二、Apple Vision Pro 的营销用例 随着苹果公司备受期待的进军可穿戴计算领域,新款 Apple Vision Pro 承载着巨大的期望。 苹果公司推出的 Vision Pro 售…

2024.7.12单片机PWM

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

[Linux]添加sudoers

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

17-8 向量数据库之野望8 - 7 个主流向量数据库

​​​​​​ 在快速发展的人工智能 (AI)、机器学习 (ML) 和数据工程领域,对高效数据存储和检索系统的需求至关重要。矢量数据库已成为管理这些技术通常依赖的复杂高维数据的关键解决方案。在这里,我们探讨了每个 AI/ML/数据工程师都应该熟悉的七个矢量数据库,重点介绍了它们…

mysql-connector-java 8.0.33 反序列化漏洞

前言 经过与oracle官方沟通,在最新的mysql-connector-j 9.0.0里不存在这个问题,所以他们不认为这是个漏洞 不过确实,mysql-connector-java这个分支已经迁移到mysql-connector-j了,当时没注意,交的时候只注意了mysql-c…

全球DeepFake攻防挑战赛DataWhale AI 夏令营——图像赛道

全球DeepFake攻防挑战赛&DataWhale AI 夏令营——图像赛道 赛题背景 随着人工智能技术的迅猛发展,深度伪造技术(Deepfake)正成为数字世界中的一把双刃剑。这项技术不仅为创意内容的生成提供了新的可能性,同时也对数字安全构…

数学建模·模糊评价法

模糊评价法 一种解决评价问题或者得出最佳方案的方法 主观性仍比较强 具体定义 三集:因素集,评语集和权重集,通过模拟矩阵的处理得到最合理的评语 具体步骤 因素集 因素集的确定不难,难在对分级评价时,对因素集的分级…

MYSQL--第九次作业

MYSQL–第九次作业 1、安装redis,启动客户端、验证。 安装网址:Redis Released,找到适合自己电脑的redis版本后,下载并安装。 安装完后,打开cmd命令框: -- 启动客户端 C:\Windows\System32>redis-cl…

AV1 编码标准帧间预测技术概述

AV1 编码标准帧间预测 AV1(AOMedia Video1)是一种开源的视频编码格式,它在帧间预测技术上做出了显著的改进和扩展,以提供比现有标准更高的压缩效率和更好的视频质量。以下是AV1帧间预测技术的几个关键点: 参考帧扩展&a…