手写实现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 disabled="false"不起作用的解决办法
Jun 26 Javascript
jquery next nextAll nextUntil siblings的区别介绍
Oct 05 Javascript
javascript中replace( )方法的使用
Apr 24 Javascript
JavaScript使用cookie实现记住账号密码功能
Apr 27 Javascript
jquery实现标题字体变换的滑动门菜单效果
Sep 07 Javascript
HTML Table 空白单元格补全的简单实现
Oct 13 Javascript
微信小程序中多个页面传参通信的学习与实践
May 05 Javascript
如何把vuejs打包出来的文件整合到springboot里
Jul 26 Javascript
详解关于JSON.parse()和JSON.stringify()的性能小测试
Mar 14 Javascript
d3.js实现图形拖拽
Dec 19 Javascript
js实现圆形显示鼠标单击位置
Feb 11 Javascript
vue页面更新patch的实现示例
Mar 25 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
php is_file 判断给定文件名是否为一个正常的文件
2010/05/10 PHP
php用数组返回无限分类的列表数据的代码
2010/08/08 PHP
php数组中删除元素的实现代码
2012/06/22 PHP
PHP数组循环操作详细介绍 附实例代码
2013/02/03 PHP
destoon调用discuz论坛中带图片帖子的实现方法
2014/08/21 PHP
PHP实现的简单留言板功能示例【基于thinkPHP框架】
2018/12/07 PHP
De facto standard 世界上不可思议的事实标准
2010/08/29 Javascript
JQuery入门——事件切换之hover()方法应用介绍
2013/02/05 Javascript
web css实现整站样式互相切换
2013/10/29 Javascript
21个值得收藏的Javascript技巧
2014/02/04 Javascript
js实现class样式的修改、添加及删除的方法
2015/01/20 Javascript
js调用百度地图及调用百度地图的搜索功能
2015/09/07 Javascript
JS实现双击屏幕滚动效果代码
2015/10/28 Javascript
javascript设置页面背景色及背景图片的方法
2015/12/29 Javascript
基于jquery编写分页插件
2016/03/07 Javascript
JS正则表达式之非捕获分组用法实例分析
2016/12/28 Javascript
Jquery树插件zTree实现菜单树
2017/01/24 Javascript
jquery实现数字输入框
2017/02/22 Javascript
Angular2学习教程之ng中变更检测问题详解
2017/05/28 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
2017/06/07 jQuery
Vue内容分发slot(全面解析)
2017/08/19 Javascript
浅谈Vue路由快照实现思路及其问题
2018/06/07 Javascript
[01:07:15]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第二场 1月25日
2021/03/11 DOTA
将Python代码打包为jar软件的简单方法
2015/08/04 Python
关于pytorch中全连接神经网络搭建两种模式详解
2020/01/14 Python
解决Python 函数声明先后顺序出现的问题
2020/09/02 Python
python批量修改文件名的示例
2020/09/27 Python
竞选文艺委员演讲稿
2014/04/28 职场文书
毕业生面试求职信
2014/06/23 职场文书
2014年初三班主任工作总结
2014/12/05 职场文书
销售员自我评价
2015/03/11 职场文书
在职证明书模板
2015/06/15 职场文书
追悼会悼词大全
2015/06/23 职场文书
2015年大学组织委员个人工作总结
2015/10/23 职场文书
餐厅如何利用“营销策略”扭转亏本局面
2019/10/15 职场文书
C站最全Python标准库总结,你想要的都在这里
2021/07/03 Python