手写实现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 相关文章推荐
onpropertypchange
Jul 01 Javascript
js 动态选中下拉框
Nov 26 Javascript
Jquery Ajax请求代码(2)
Jan 07 Javascript
文本有关的样式和jQuery求对象的高宽问题分别说明
Aug 30 Javascript
基于javascript实现表格的简单操作
May 21 Javascript
最佳的JavaScript错误处理实践
Jul 16 Javascript
80%应聘者都不及格的JS面试题
Mar 21 Javascript
基于vue2实现上拉加载功能
Nov 28 Javascript
Vue循环组件加validate多表单验证的实例
Sep 18 Javascript
Vue项目引发的「过滤器」使用教程
Mar 12 Javascript
JS前后端实现身份证号验证代码解析
Jul 23 Javascript
解决vue的router组件component在import时不能使用变量问题
Jul 26 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
网站加速 PHP 缓冲的免费实现方法
2006/10/09 PHP
提升PHP性能的21种方法介绍
2013/06/25 PHP
强制PHP命令行脚本单进程运行的方法
2014/04/15 PHP
php出现内存位置访问无效错误问题解决方法
2014/08/16 PHP
php利用smtp类实现电子邮件发送
2015/10/30 PHP
PHP实现文字写入图片功能
2019/02/18 PHP
一段效率很高的for循环语句使用方法
2007/08/13 Javascript
js字符串的各种格式的转换 ToString,Format
2011/08/08 Javascript
几种延迟加载JS代码的方法加快网页的访问速度
2013/10/12 Javascript
JS将所有对象s的属性复制给对象r(原生js+jquery)
2014/01/25 Javascript
jquery 页面滚动到底部自动加载插件集合
2014/01/31 Javascript
浅谈javascript中for in 和 for each in的区别
2015/04/23 Javascript
jQuery中使用each处理json数据
2015/04/23 Javascript
详细解读Jquery各Ajax函数($.get(),$.post(),$.ajax(),$.getJSON())
2016/08/15 Javascript
微信小程序中的onLoad详解及简单实例
2017/04/05 Javascript
基于Vue实现timepicker
2017/04/25 Javascript
VUE axios发送跨域请求需要注意的问题
2017/07/06 Javascript
使用javaScript实现鼠标拖拽事件
2020/04/03 Javascript
vue如何进行动画的封装
2018/09/26 Javascript
小结Python用fork来创建子进程注意事项
2014/07/03 Python
python获得linux下所有挂载点(mount points)的方法
2015/04/29 Python
Python中matplotlib中文乱码解决办法
2017/05/12 Python
Python根据欧拉角求旋转矩阵的实例
2019/01/28 Python
Python中py文件转换成exe可执行文件的方法
2019/06/14 Python
django 配置阿里云OSS存储media文件的例子
2019/08/20 Python
Python threading的使用方法解析
2019/08/28 Python
Django自定义用户表+自定义admin后台中的字段实例
2019/11/18 Python
Python Numpy数组扩展repeat和tile使用实例解析
2019/12/09 Python
python3+opencv 使用灰度直方图来判断图片的亮暗操作
2020/06/02 Python
python爬取2021猫眼票房字体加密实例
2021/02/19 Python
HTML5和CSS3让网页设计提升到下一个高度
2009/08/14 HTML / CSS
html5中去掉input type date默认样式的方法
2018/09/06 HTML / CSS
捷克家电和家具购物网站:OKAY.cz
2020/07/23 全球购物
美国家居装饰购物网站:Amanda Lindroth
2020/03/25 全球购物
机械个人求职信范文
2014/01/24 职场文书
违反交通法规检讨书
2014/09/10 职场文书