手写实现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 相关文章推荐
juqery 学习之五 文档处理 包裹、替换、删除、复制
Feb 11 Javascript
javascript 图片裁剪技巧解读
Nov 15 Javascript
js 文本滚动效果的实例代码
Aug 17 Javascript
js解决select下拉选不中问题
Oct 14 Javascript
JavaScript实现三阶幻方算法谜题解答
Dec 29 Javascript
JavaScript删除指定子元素代码实例
Jan 13 Javascript
jQuery中的siblings用法实例分析
Dec 24 Javascript
Three.js 再探 - 写一个微信跳一跳极简版游戏
Jan 04 Javascript
微信小程序实现点赞、取消点赞功能
Nov 02 Javascript
一个因@click.stop引发的bug的解决
Jan 08 Javascript
js实现全选反选不选功能代码详解
Apr 24 Javascript
OpenLayers3实现测量功能
Sep 25 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
在PHP3中实现SESSION的功能(二)
2006/10/09 PHP
PHP使用第三方即时获取物流动态实例详解
2017/04/27 PHP
PHP实现从上往下打印二叉树的方法
2018/01/18 PHP
HTA版JSMin(省略修饰语若干)基于javascript语言编写
2009/12/24 Javascript
ModelDialog JavaScript模态对话框类代码
2011/04/17 Javascript
js日历功能对象
2012/01/12 Javascript
jquery表单验证使用插件formValidator
2012/11/10 Javascript
js如何调用qq互联api实现第三方登录
2014/03/28 Javascript
js实现遮罩层划出效果是生成div而不是显示
2014/07/29 Javascript
Angularjs过滤器使用详解
2016/05/25 Javascript
第一次接触神奇的Bootstrap表单
2016/07/27 Javascript
React组件的三种写法总结
2017/01/12 Javascript
PHP7新特性简述
2017/06/11 Javascript
基于es6三点运算符的使用方法(实例讲解)
2017/10/12 Javascript
转换layUI的数据表格中的日期格式方法
2019/09/19 Javascript
js操作两个json数组合并、去重,以及删除某一项元素
2020/09/22 Javascript
微信小程序自定义tabBar的踩坑实践记录
2020/11/06 Javascript
python爬虫实现教程转换成 PDF 电子书
2017/02/19 Python
Python基于scapy实现修改IP发送请求的方法示例
2017/07/08 Python
Python开发企业微信机器人每天定时发消息实例
2020/03/17 Python
python 如何区分return和yield
2020/09/22 Python
Selenium关闭INFO:CONSOLE提示的解决
2020/12/07 Python
一款利用html5和css3动画排列人物头像的实例演示
2014/12/05 HTML / CSS
迪卡侬印度官网:购买所有体育用品
2017/06/24 全球购物
Tirendo比利时:在线购买轮胎
2018/10/22 全球购物
台湾7-ELEVEN线上购物中心:7-11
2021/01/21 全球购物
2014三八妇女节活动总结
2014/03/01 职场文书
体育专业自荐书
2014/05/29 职场文书
乡镇八一建军节活动方案
2014/08/24 职场文书
单位委托书范本(3篇)
2014/09/18 职场文书
大学生联谊活动策划书(光棍节)
2014/10/10 职场文书
2014年教师教学工作总结
2014/11/08 职场文书
2019入党申请书范文3篇
2019/08/21 职场文书
浅谈如何提高PHP代码的质量
2021/05/28 PHP
如何利用Python实现一个论文降重工具
2021/07/09 Python
python编程实现清理微信重复缓存文件
2021/11/01 Python