手写实现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中 noConflict() 方法使用
Apr 25 Javascript
js特效,页面下雪的小例子
Jun 17 Javascript
导航跟随滚动条置顶移动示例代码
Sep 11 Javascript
javascript使用window.open提示“已经计划系统关机”的原因
Aug 15 Javascript
在AngularJS框架中处理数据建模的方式解析
Mar 05 Javascript
使用jquery获取url以及jquery获取url参数的实现方法
May 25 Javascript
jQuery树控件zTree使用方法详解(一)
Feb 28 Javascript
JavaScript中的FileReader图片预览上传功能实现代码
Jul 24 Javascript
详解webpack + react + react-router 如何实现懒加载
Nov 20 Javascript
微信小程序页面间值传递的两种方法
Nov 26 Javascript
JS使用new操作符创建对象的方法分析
May 30 Javascript
JavaScript单线程和任务队列原理解析
Feb 04 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
程序员编程十条戒律
2009/07/09 PHP
PHP+SQL 注入攻击的技术实现以及预防办法
2010/12/29 PHP
PHP中多线程的两个实现方法
2016/10/14 PHP
JS实现的省份级联实例代码
2013/06/24 Javascript
JS关闭窗口或JS关闭页面的几种代码分享
2013/10/25 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 简史
2015/01/09 Javascript
深入理解jQuery3.0的domManip函数
2016/09/01 Javascript
JS动态的把左边列表添加到右边的实现代码(可上下移动)
2016/11/17 Javascript
vue组件父子间通信之综合练习(聊天室)
2017/11/07 Javascript
浅谈Vue CLI 3结合Lerna进行UI框架设计
2019/04/14 Javascript
Vue 请求传公共参数的操作
2020/07/31 Javascript
bootstrap实现tab选项卡切换
2020/08/09 Javascript
maptalks+three.js+vue webpack实现二维地图上贴三维模型操作
2020/08/10 Javascript
[01:14]DOTA2 7.22版本新增神杖效果展示(智力英雄篇)
2019/05/29 DOTA
wxpython 学习笔记 第一天
2009/03/16 Python
Python中强大的命令行库click入门教程
2016/12/26 Python
便捷提取python导入包的属性方法
2018/10/15 Python
python获取全国城市pm2.5、臭氧等空气质量过程解析
2019/10/12 Python
Python调用scp向服务器上传文件示例
2019/12/22 Python
pyftplib中文乱码问题解决方案
2020/01/11 Python
Python如何实现FTP功能
2020/05/28 Python
为智能设备设计个性化保护套网站:caseable
2017/01/05 全球购物
英国网上购买门:Direct Doors
2018/06/07 全球购物
英国最大的香水商店:The Fragrance Shop
2018/07/06 全球购物
台湾家适得:Homeget
2019/02/11 全球购物
LORAC官网:美国彩妆品牌
2019/08/27 全球购物
中专毕业个人的自荐信格式
2013/09/21 职场文书
最新自我评价范文
2013/11/16 职场文书
二手书店创业计划书
2014/01/16 职场文书
《小松树和大松树》教学反思
2014/02/20 职场文书
民主评议政风行风整改方案
2014/09/17 职场文书
见习报告怎么写
2014/10/31 职场文书
HTML页面滚动时部分内容位置固定不滚动的实现
2021/04/14 HTML / CSS
MySQL 8.0 驱动与阿里druid版本兼容问题解决
2021/07/01 MySQL
让JavaScript代码更加精简的方法技巧
2022/06/01 Javascript
jdbc中自带MySQL 连接池实践示例
2022/07/23 MySQL