手写实现JS中的new


Posted in Javascript onNovember 07, 2021

⚠ 预备知识:

  • 了解原型和原型链
  • 了解this绑定

1 new 运算符简介

MDN文档:new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

class Person {
    constructor(name) {
        this.name = name;
    }
}
// 创建自定义对象类型的实例
const person = new Person('小明')
// 创建具有构造函数的内置对象的实例
const date = new Date()

new的作用:创建对象的实例

2 new 究竟干了什么事

上面说了new的作用是创建对象的实例,那么它究竟是怎么创建实例的,内部干了哪几件事?

以new Person()为例,当它执行时,会发生以下事情:

创建一个空的简单JS对象

const obj = {}

给这个对象添加属性__proto__,并将该属性链接到构造函数的原型对象

obj.__proto__ = Person.prototype

调用构造函数Person,并将this绑定到新创建的对象obj

Person.apply(obj)

如果构造函数没有显式返回一个对象,则返回新创建的对象,即obj

3 模拟实现 new 运算符

如上所述,new运算符就干了这么4件事,下面我们就根据这4个步骤用函数来模拟实现new(面试手写代码)

const _new = function(constructor, ...args) {
    const obj = {}
    obj.__proto__ = constructor.prototype
    const res = constructor.apply(obj, args)
    // 这一步在"补充"中会详细解释
    return res instanceof Object ? res : obj
}

代码非常简单,就是按照上面4步,一步一步写就可以了

4 补充

ES5提供了Object.create方法,该方法可以创建一个对象,并让新对象的__proto__属性指向已经存在的对象。

所以我们可以使用这个方法合并1、2两步

const obj = Object.create(constructor.prototype)
// 等价于
const obj = {}
obj.__proto__ = constructor.prototype

对于第4步,再解释一下

  • 如果构造函数没有显式return(通常情况)那么person就是新创建的对象obj
  • 如果构造函数返回的不是一个对象,比如1、"abc" 那么person还是新创建的对象obj
function Person() {
    ...
   return 1
}

如果构造函数显式返回了一个对象,比如{}function() {}

那么person就不是新创建的对象obj了,而是显式return的这个对象

function Person() {
  // 函数也是对象
  return function() {}
}

所以我们在_new函数最后一句代码是:

return res instanceof Object ? res : obj

注意:模拟实现的函数_new传入的参数只能是构造函数,不能是类

class Animal {  ...}_new(Animal)// 会报错:Class constructor Animal cannot be invoked without 'new'// 类只能通过new来创建

到此这篇关于手写实现JS中的new的文章就介绍到这了,更多相关JS中的new内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
js返回上一页并刷新代码整理
Dec 21 Javascript
Three.js源码阅读笔记(光照部分)
Dec 27 Javascript
jquery判断复选框是否被选中的方法
Oct 16 Javascript
跟我学习javascript的定时器
Nov 19 Javascript
实例讲解JS中setTimeout()的用法
Jan 28 Javascript
解决vue js IOS H5focus无法自动弹出键盘的问题
Aug 30 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
Mar 29 Javascript
微信小程序配置服务器提示验证token失败的解决方法
Apr 03 Javascript
详解基于mpvue微信小程序下载远程图片到本地解决思路
May 16 Javascript
vue2.0 实现富文本编辑器功能
May 26 Javascript
Vue + Element UI图片上传控件使用详解
Aug 20 Javascript
react中hook介绍以及使用教程
Dec 11 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
php设计模式之命令模式使用示例
2014/03/02 PHP
php生成过去100年下拉列表的方法
2015/07/20 PHP
Laravel 中获取上一篇和下一篇数据
2015/07/27 PHP
PHP比较运算符的详细介绍
2015/09/29 PHP
PHP的时间戳与具体时间转化的简单实现
2016/06/13 PHP
PHP7 弃用功能
2021/03/09 PHP
JSON 学习之完全手册 图文
2007/05/29 Javascript
jquery中通过过滤器获取表单元素的实现代码
2011/07/05 Javascript
Javascript根据指定下标或对象删除数组元素
2012/12/21 Javascript
jquery写个checkbox——类似邮箱全选功能
2013/03/19 Javascript
jquery自动填充勾选框即把勾选框打上true
2014/03/24 Javascript
jQuery实现返回顶部功能适合不支持js的浏览器
2014/08/19 Javascript
Javascript基础教程之while语句
2015/01/18 Javascript
Javascript实现鼠标右键特色菜单
2015/08/04 Javascript
JS+HTML5实现上传图片预览效果完整实例【测试可用】
2017/04/20 Javascript
React-Native之定时器Timer的实现代码
2017/10/04 Javascript
解决vue组件中使用v-for出现告警问题及v for指令介绍
2017/11/11 Javascript
Angular 4.x+Ionic3踩坑之Ionic3.x pop反向传值详解
2018/03/13 Javascript
Vue axios与Go Frame后端框架的Options请求跨域问题详解
2020/03/03 Javascript
如何在vue 中引入使用jquery
2020/11/10 jQuery
python标准日志模块logging的使用方法
2013/11/01 Python
在python的WEB框架Flask中使用多个配置文件的解决方法
2014/04/18 Python
flask入门之文件上传与邮件发送示例
2018/07/18 Python
python 实现的发送邮件模板【普通邮件、带附件、带图片邮件】
2019/07/06 Python
python隐藏类中属性的3种实现方法
2019/12/19 Python
Python eval函数介绍及用法
2020/11/09 Python
应届生高等护理求职信
2013/10/12 职场文书
优秀毕业生事迹材料
2014/02/12 职场文书
庆元旦迎新年广播稿
2014/02/18 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书
学生上课说话检讨书
2014/10/25 职场文书
西安兵马俑导游词
2015/02/02 职场文书
内乡县衙导游词
2015/02/05 职场文书
入学证明
2015/06/23 职场文书
详细介绍Java中的CyclicBarrier
2022/04/13 Java/Android
MySQL 字符集 character
2022/05/04 MySQL