手写实现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 相关文章推荐
JavaScript 学习笔记(十三)Dom创建表格
Jan 21 Javascript
jquery 使用简明教程
Mar 05 Javascript
Extjs表单常见验证小结
Mar 07 Javascript
js弹出确认是否删除对话框
Mar 27 Javascript
JavaScript拆分字符串时产生空字符的解决方案
Sep 26 Javascript
js实现按钮控制图片360度翻转特效的方法
Feb 17 Javascript
原生JS封装Ajax插件(同域、jsonp跨域)
May 03 Javascript
jQuery ready()和onload的加载耗时分析
Sep 08 Javascript
分分钟学会vue中vuex的应用(入门教程)
Sep 14 Javascript
jQuery滚动条美化插件nicescroll简单用法示例
Apr 18 jQuery
CKeditor4 字体颜色功能配置方法教程
Jun 26 Javascript
为什么Vue3.0使用Proxy实现数据监听(defineProperty表示不背这个锅)
Oct 14 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
php a simple smtp class
2007/11/26 PHP
PHP连接MongoDB示例代码
2012/09/06 PHP
php面向对象之反射功能与用法分析
2017/03/29 PHP
PHP数据库操作二:memcache用法分析
2017/08/16 PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
2018/04/20 PHP
Google韩国首页图标动画效果
2007/08/26 Javascript
js多功能分页组件layPage使用方法详解
2016/05/19 Javascript
JS常用字符串方法(推荐)
2021/01/15 Javascript
Node.js中使用mongoose操作mongodb数据库的方法
2017/09/12 Javascript
详解node child_process模块学习笔记
2018/01/24 Javascript
vue bus全局事件中心简单Demo详解
2018/02/26 Javascript
小程序实现发表评论功能
2018/07/06 Javascript
vue监听对象及对象属性问题
2018/08/20 Javascript
JS用最简单的方法实现四舍五入
2019/08/27 Javascript
Vue.directive 实现元素scroll逻辑复用
2019/11/29 Javascript
[03:17]2014DOTA2 国际邀请赛中国区预选赛 四强专访
2014/05/23 DOTA
使用setup.py安装python包和卸载python包的方法
2013/11/27 Python
Python压缩解压缩zip文件及破解zip文件密码的方法
2015/11/04 Python
解析Python中的__getitem__专有方法
2016/06/27 Python
python3实现UDP协议的服务器和客户端
2017/06/14 Python
Python实现调度算法代码详解
2017/12/01 Python
python 2.7.13 安装配置方法图文教程
2018/09/18 Python
python2.7 安装pip的方法步骤(管用)
2019/05/05 Python
Tensorflow中的dropout的使用方法
2020/03/13 Python
使用Python制作一个数据预处理小工具(多种操作一键完成)
2021/02/07 Python
一款纯css3实现的动画加载导航
2014/10/08 HTML / CSS
全球最大的在线旅游公司:Expedia
2017/11/16 全球购物
NBA德国官方网上商店:NBA Store德国
2018/04/13 全球购物
2014年物流工作总结
2014/11/25 职场文书
写给女朋友的检讨书
2015/05/06 职场文书
《平行四边形的面积》教学反思
2016/02/16 职场文书
2019年让高校“心动”的自荐信
2019/03/25 职场文书
应用最多的公文《通知》如何写?
2019/04/02 职场文书
导游词之丽江普济寺
2019/10/22 职场文书
聊聊SpringBoot自动装配的魔力
2021/11/17 Java/Android
python如何查找列表中元素的位置
2022/05/30 Python