手写实现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图片轮播的具体实现
Sep 11 Javascript
javascript教程之不完整的继承(js原型链)
Jan 13 Javascript
jquery Validation表单验证使用详解
Sep 12 Javascript
JavaScript SHA512加密算法详细代码
Oct 06 Javascript
基于JS脚本语言的基础语法详解
Jul 22 Javascript
Angular 向组件传递模板的两种方法
Feb 23 Javascript
详解Vue iview IE浏览器不兼容报错(Iview Bable polyfill)
Jan 07 Javascript
js中数组对象去重的两种方法
Jan 18 Javascript
深入了解JavaScript 的 WebAssembly
Jun 15 Javascript
JavaScript 扩展运算符用法实例小结【基于ES6】
Jun 17 Javascript
React Native 混合开发多入口加载方式详解
Sep 23 Javascript
React Native项目框架搭建的一些心得体会
May 28 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
超人钢铁侠联手合作?美漫作家呼吁DC漫威合作联动以抵抗疫情
2020/04/09 欧美动漫
How do I change MySQL timezone?
2008/03/26 PHP
PHP中图片等比缩放的实例
2013/03/24 PHP
Yii框架调试心得--在页面输出执行sql语句
2014/12/25 PHP
php读取csv数据保存到数组的方法
2015/01/03 PHP
PHP+mysql实现的三级联动菜单功能示例
2019/02/15 PHP
php装饰者模式简单应用案例分析
2019/10/23 PHP
PHP 使用位运算实现四则运算的代码
2021/03/09 PHP
JavaScript语句可以不以;结尾的烦恼
2007/03/08 Javascript
跟着JQuery API学Jquery 之三 筛选
2010/04/09 Javascript
一个挺有意思的Javascript小问题说明
2011/09/26 Javascript
下拉框select的绑定示例
2014/09/04 Javascript
iframe里使用JavaScript控制主页转向的方法
2015/04/03 Javascript
ECMAScript6函数默认参数
2015/06/12 Javascript
Bootstrap每天必学之栅格系统(布局)
2015/11/25 Javascript
深入理解jQuery之防止冒泡事件
2016/05/24 Javascript
react 创建单例组件的方法
2018/04/26 Javascript
对于Python的Django框架部署的一些建议
2015/04/09 Python
使用Python的Tornado框架实现一个一对一聊天的程序
2015/04/25 Python
django实现分页的方法
2015/05/26 Python
Python3控制路由器——使用requests重启极路由.py
2016/05/11 Python
Python多进程multiprocessing用法实例分析
2017/08/18 Python
详解python使用Nginx和uWSGI来运行Python应用
2018/01/09 Python
python实现换位加密算法的示例
2018/10/14 Python
python实现从pdf文件中提取文本,并自动翻译的方法
2018/11/28 Python
Django开发的简易留言板案例详解
2018/12/04 Python
维多利亚的秘密官方网站:Victoria’s Secret
2018/10/24 全球购物
智能电子秤、手表和健康监测仪:Withings(之前为诺基亚健康)
2018/10/30 全球购物
爱尔兰电脑、家电和家具购物网站:Buy It Direct
2019/07/09 全球购物
Collection和Collections的区别
2016/05/02 面试题
大学班级计划书
2014/04/29 职场文书
工程质量保证书
2015/05/09 职场文书
责任书格式
2019/04/18 职场文书
心得体会该怎么写呢?
2019/06/27 职场文书
《辉夜大小姐想让我告白》第三季正式预告
2022/03/20 日漫
ubuntu开机后ROS程序自启动问题
2022/12/24 Servers