手写实现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 相关文章推荐
Jquery封装tab自动切换效果的具体实现
Jul 13 Javascript
目前流行的JavaScript库的介绍及对比
Sep 29 Javascript
5秒后跳转到另一个页面的js代码
Oct 12 Javascript
使用JS+plupload直接批量上传图片到又拍云
Dec 01 Javascript
jQueryMobile之Helloworld与页面切换的方法
Feb 04 Javascript
基于jquery实现瀑布流布局
Jun 28 Javascript
利用Ionic2 + angular4实现一个地区选择组件
Jul 27 Javascript
jQuery ajax读取本地json文件的实例
Oct 31 jQuery
关于angularJs清除浏览器缓存的方法
Nov 28 Javascript
在vue项目中引入高德地图及其UI组件的方法
Sep 04 Javascript
基于layui table返回的值的多级嵌套的解决方法
Sep 19 Javascript
Ant Design的可编辑Tree的实现操作
Oct 31 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
PHP中全局变量global和$GLOBALS[]的区别分析
2012/08/06 PHP
Thinkphp3.2实用篇之计算型验证码示例
2017/02/09 PHP
PHP使用ActiveMQ实现消息队列的方法详解
2019/05/31 PHP
Jquery实现瀑布流布局(备有详细注释)
2015/07/31 Javascript
Bootstrap警告(Alerts)的实现方法
2017/03/22 Javascript
JavaScript制作简单的框选图表
2017/05/15 Javascript
Vue2.0+ElementUI实现表格翻页的实例
2017/10/23 Javascript
微信小程序实现文字无限轮播效果
2018/12/28 Javascript
vue添加class样式实例讲解
2019/02/12 Javascript
简单使用webpack打包文件的实现
2019/10/29 Javascript
写给新手同学的vuex快速上手指北小结
2020/04/14 Javascript
python 接口_从协议到抽象基类详解
2017/08/24 Python
django自带的server 让外网主机访问方法
2018/05/14 Python
Django中的Model操作表的实现
2018/07/24 Python
Python import与from import使用及区别介绍
2018/09/06 Python
python+Splinter实现12306抢票功能
2018/09/25 Python
python3.x实现base64加密和解密
2019/03/28 Python
python之当你发现QTimer不能用时的解决方法
2019/06/21 Python
java中的控制结构(if,循环)详解
2019/06/26 Python
在win64上使用bypy进行百度网盘文件上传功能
2020/01/02 Python
python无序链表删除重复项的方法
2020/01/17 Python
Python容器类型公共方法总结
2020/08/19 Python
Python 实现PS滤镜中的径向模糊特效
2020/12/03 Python
罗兰·穆雷官网:Roland Mouret
2018/09/28 全球购物
JD Sports芬兰:英国领先的运动鞋和运动服饰零售商
2018/11/16 全球购物
Rhone官方网站:男士运动服装、健身服装和高级运动服
2019/05/01 全球购物
德国排名第一的主题公园门票网站:Attraction Tickets Direct
2019/09/09 全球购物
香港家用健身器材、运动器材及健康美容仪器专门店:FitBoxx
2019/12/05 全球购物
银行见习期自我鉴定
2014/01/29 职场文书
《小草和大树》教学反思
2014/02/16 职场文书
英语演讲稿3分钟
2014/04/29 职场文书
授权委托书样本
2014/09/25 职场文书
群众路线党员个人剖析材料
2014/10/08 职场文书
扬州个园导游词
2015/02/06 职场文书
幼儿教师继续教育培训心得体会
2016/01/19 职场文书
oracle索引总结
2021/09/25 Oracle