当前位置: 首页 > news >正文

手写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)

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 勒索防御第一关 亚信安全AE防毒墙全面升级 勒索检出率提升150%
  • 技术周总结 2024.07.08~07.14(算法,Python,Java,Scala,PHP)
  • 【Linux网络】poll{初识poll / poll接口 / poll vs select / poll开发多客户端echo服务器}
  • ABC分析模型详解
  • MetaGPT和LangGraph对比
  • 10款性价比高的销售管理信息系统推荐
  • Qt实现MDI应用程序
  • 如何在gitee上创建远程仓库?
  • 对于GPT-5在一年半后发布的期待!
  • 数据库管理-第218期 服务器内存(20240711)
  • 【C语言】移位操作详解 - 《凌波微步 ! 》
  • JS-11G1端子排静态时间继电器 约瑟JOSEF
  • Centos忘记密码,重置root密码
  • R语言学习笔记7-列表
  • Raw Socket(二)循环队列收发数据
  • Android单元测试 - 几个重要问题
  • Android开源项目规范总结
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Invalidate和postInvalidate的区别
  • JAVA 学习IO流
  • Linux链接文件
  • magento 货币换算
  • Markdown 语法简单说明
  • mongodb--安装和初步使用教程
  • mysql常用命令汇总
  • nginx 负载服务器优化
  • QQ浏览器x5内核的兼容性问题
  • Swift 中的尾递归和蹦床
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 工作中总结前端开发流程--vue项目
  • 力扣(LeetCode)965
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 微信开放平台全网发布【失败】的几点排查方法
  • 学习JavaScript数据结构与算法 — 树
  • ​数据链路层——流量控制可靠传输机制 ​
  • !!java web学习笔记(一到五)
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (13):Silverlight 2 数据与通信之WebRequest
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (Python第六天)文件处理
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转) ns2/nam与nam实现相关的文件
  • (转)Sql Server 保留几位小数的两种做法
  • .gitignore文件忽略的内容不生效问题解决
  • .Net Core中的内存缓存实现——Redis及MemoryCache(2个可选)方案的实现
  • .NET 发展历程
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .net6 webapi log4net完整配置使用流程
  • .net解析传过来的xml_DOM4J解析XML文件