手写实现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 相关文章推荐
utf8的编码算法 转载
Dec 27 Javascript
JavaScript入门教程(12) js对象化编程
Jan 31 Javascript
CodeMirror2 IE7/IE8 下面未知运行时错误的解决方法
Mar 29 Javascript
json格式的时间显示为正常年月日的方法
Sep 08 Javascript
Vue.js实现一个todo-list的上移下移删除功能
Jun 26 Javascript
Javascript中toFixed计算错误(依赖银行家舍入法的缺陷)解决方法
Aug 22 Javascript
js操作二进制数据方法
Mar 03 Javascript
记录一篇关于redux-saga的基本使用过程
Aug 18 Javascript
vue中node_modules中第三方模块的修改使用详解
May 31 Javascript
JavaScript实现简单进度条效果
Mar 25 Javascript
vue内置组件component--通过is属性动态渲染组件操作
Jul 28 Javascript
PHP 502bad gateway原因及解决方案
Nov 13 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
配置最新的PHP加MYSQL服务器
2006/10/09 PHP
php多功能图片处理类分享(php图片缩放类)
2014/03/14 PHP
调用WordPress函数统计文章访问量及PHP原生计数器的实现
2016/03/21 PHP
解决在laravel中auth建立时候遇到的问题
2019/10/15 PHP
设定php简写功能的方法
2019/11/28 PHP
cnblogs csdn 代码运行框实现代码
2009/11/02 Javascript
js 键盘记录实现(兼容FireFox和IE)
2010/02/07 Javascript
学好js,这些js函数概念一定要知道【推荐】
2017/01/19 Javascript
jQuery图片轮播功能实例代码
2017/01/29 Javascript
vue2笔记 — vue-router路由懒加载的实现
2017/03/03 Javascript
vue实现移动端图片裁剪上传功能
2020/08/18 Javascript
深入理解Vue 组件之间传值
2018/08/16 Javascript
移动端图片上传旋转、压缩问题的方法
2018/10/16 Javascript
JS实现判断有效的数独算法示例
2019/02/25 Javascript
微信小程序调用微信支付接口的实现方法
2019/04/29 Javascript
[01:06]DOTA2小知识课堂 Ep.01 TP出门不要忘记帮队友灌瓶哦
2019/12/05 DOTA
利用Python中的pandas库对cdn日志进行分析详解
2017/03/07 Python
Python使用ctypes调用C/C++的方法
2019/01/29 Python
Python3.5基础之变量、数据结构、条件和循环语句、break与continue语句实例详解
2019/04/26 Python
python开启debug模式的方法
2019/06/27 Python
Python爬虫使用代理IP的实现
2019/10/27 Python
Python树莓派学习笔记之UDP传输视频帧操作详解
2019/11/15 Python
python3 实现调用串口功能
2019/12/26 Python
pandas中的数据去重处理的实现方法
2020/02/10 Python
python实现银行实战系统
2020/02/26 Python
通过Python扫描代码关键字并进行预警的实现方法
2020/05/24 Python
CSS3 Media Queries详细介绍和使用实例
2014/05/08 HTML / CSS
canvas实现滑动验证的实现示例
2020/08/11 HTML / CSS
自荐信怎么写好
2013/11/11 职场文书
魅力教师事迹材料
2014/01/10 职场文书
《悯农》教学反思
2014/04/28 职场文书
保研推荐信格式
2015/03/25 职场文书
2015年小学生国庆节演讲稿
2015/07/30 职场文书
七年级语文教学反思
2016/03/03 职场文书
在vue中import()语法不能传入变量的问题及解决
2022/04/01 Vue.js
在容器中使用nginx搭建上传下载服务器
2022/05/11 Servers