手写实现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 相关文章推荐
发两个小东西,ASP/PHP 学习工具。 用JavaScript写的
Apr 12 Javascript
热点新闻滚动特效的js代码
Aug 17 Javascript
js跨域问题浅析及解决方法优缺点对比
Nov 08 Javascript
Javascript中的几种URL编码方法比较
Jan 23 Javascript
jquery让指定的元素闪烁显示的方法
Mar 17 Javascript
底部悬浮通栏可以关闭广告位的实现方法
Jun 01 Javascript
JS实现n秒后自动跳转的两种方法
Nov 30 Javascript
AngularJS折叠菜单实现方法示例
May 18 Javascript
webpack教程之webpack.config.js配置文件
Jul 05 Javascript
详解angular应用容器化部署
Aug 14 Javascript
vscode vue 文件模板的配置方法
Jul 23 Javascript
JS高级程序设计之class继承重点详解
Jul 07 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
全国FM电台频率大全 - 29 青海省
2020/03/11 无线电
编译问题
2006/10/09 PHP
php 操作数组(合并,拆分,追加,查找,删除等)
2012/07/20 PHP
php引用计数器进行垃圾收集机制介绍
2012/09/19 PHP
PHP5.3的垃圾回收机制(动态存储分配方案)深入理解
2012/12/10 PHP
PHP永久登录、记住我功能实现方法和安全做法
2015/04/27 PHP
简单的php+mysql聊天室实现方法(附源码)
2016/01/05 PHP
javascript加号"+"的二义性说明
2013/03/04 Javascript
对frameset、frame、iframe的js操作示例代码
2013/08/16 Javascript
Javascript设计模式之观察者模式的多个实现版本实例
2015/03/03 Javascript
jquery ajax分页插件的简单实现
2016/01/27 Javascript
快速使用Bootstrap搭建传送带
2016/05/06 Javascript
jQuery常用选择器详解
2017/07/17 jQuery
vue移动端项目缓存问题实践记录
2018/10/29 Javascript
微信小程序通过js实现瀑布流布局详解
2019/08/28 Javascript
VUE实现密码验证与提示功能
2019/10/18 Javascript
小程序如何定位所在城市及发起周边搜索
2020/02/11 Javascript
[01:10]3.19DOTA2发布会 三代刀塔人第一代
2014/03/25 DOTA
[57:28]2018DOTA2亚洲邀请赛 4.6 淘汰赛 TNC vs Liquid 第一场
2018/04/10 DOTA
Python使用urllib2模块抓取HTML页面资源的实例分享
2016/05/03 Python
python去掉空白行的多种实现代码
2018/03/19 Python
python中将\\uxxxx转换为Unicode字符串的方法
2018/09/06 Python
Python从使用线程到使用async/await的深入讲解
2018/09/16 Python
理想高通滤波实现Python opencv示例
2019/01/30 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
2019/10/11 Python
Python列表元素常见操作简单示例
2019/10/25 Python
Python解析json代码实例解析
2019/11/25 Python
Pycharm如何运行.py文件的方法步骤
2020/03/03 Python
Python绘制全球疫情变化地图的实例代码
2020/04/20 Python
Python替换NumPy数组中大于某个值的所有元素实例
2020/06/08 Python
使用Keras 实现查看model weights .h5 文件的内容
2020/06/09 Python
HTML5各种头部meta标签的功能(推荐)
2017/03/13 HTML / CSS
社会体育专业大学生职业生涯规划书
2014/09/17 职场文书
原料仓管员岗位职责
2015/04/01 职场文书
战友聚会致辞
2015/07/28 职场文书
[有人@你]你有一封绿色倡议书,请查收!
2019/07/18 职场文书