面试官:熟悉JS中的new吗?能手写实现吗?
预备知识:
- 了解原型和原型链
- 了解
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绑定到新创建的对象objPerson.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还是新创建的对象objfunction 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吗?能手写实现吗?的更多相关文章
- 面试官:Redis中字符串的内部实现方式是什么?
在面试间里等候时,感觉这可真暖和呀,我那冰冷的出租屋还得盖两层被子才能睡着.正要把外套脱下来,我突然听到了门外的脚步声,随即门被打开,穿着干净满脸清秀的青年走了进来,一股男士香水的淡香扑面而来. 面试 ...
- 面试官:Redis中哈希数据类型的内部实现方式是什么?
面试官:Redis中基本的数据类型有哪些? 我:Redis的基本数据类型有:字符串(string).哈希(hash).列表(list).集合(set).有序集合(zset). 面试官:哈希数据类型的内 ...
- 面试官:Redis中集合数据类型的内部实现方式是什么?
虽然已经是阳春三月,但骑着共享单车骑了这么远,还有有点冷的.我搓了搓的被冻的麻木的手,对着前台的小姐姐说:"您好,我是来面试的."小姐姐问:"您好,您叫什么名字?&quo ...
- 面试官:Redis中有序集合的内部实现方式是什么?
面试官:Redis中基本的数据类型有哪些? 我:Redis的基本数据类型有:字符串(string).哈希(hash).列表(list).集合(set).有序集合(zset). 面试官:有序集合的内部实 ...
- 【高并发】面试官:Java中提供了synchronized,为什么还要提供Lock呢?
写在前面 在Java中提供了synchronized关键字来保证只有一个线程能够访问同步代码块.既然已经提供了synchronized关键字,那为何在Java的SDK包中,还会提供Lock接口呢?这是 ...
- 【性能优化】面试官:Java中的对象都是在堆上分配的吗?
写在前面 从开始学习Java的时候,我们就接触了这样一种观点:Java中的对象是在堆上创建的,对象的引用是放在栈里的,那这个观点就真的是正确的吗?如果是正确的,那么,面试官为啥会问:"Jav ...
- 面试官:Redis中列表的内部实现方式是什么?
在面试间里等候时,感觉这可真暖和呀,我那冰冷的出租屋还得盖两层被子才能睡着.正要把外套脱下来,我突然听到了门外的脚步声,随即门被打开,一位眉毛弯弯嘴唇红红的小姐姐走了进来,甜甜的香水味立刻钻进了我的鼻 ...
- 面试官:Java中对象都存放在堆中吗?你知道逃逸分析?
面试官:Java虚拟机的内存分为哪几个区域? 我(微笑着):程序计数器.虚拟机栈.本地方法栈.堆.方法区 面试官:对象一般存放在哪个区域? 我:堆. 面试官:对象都存放在堆中吗? 我:是的. 面试官: ...
- 面试官:Zookeeper怎么解决读写、双写并发不一致问题,以及共享锁的实现原理?
哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 今天清明假期,赶上北京玉渊潭公园 ...
随机推荐
- STM32CbueIDE 与 J-Link
STM32CbueIDE 与 J-Link 无论是 STM32CbueIDE 还是 Keil, 在使用 JLink 的时候都不过是先启 JLink 的 GDB 服务,然后再"远程" ...
- PHP中命名空间是怎样的存在?(三)
这是与命名空间有关的最后一篇.最后还是两个比较简单的内容,是关于命名空间和全局相关的一些类.函数.常量的使用对比.当然,最后我们还会总结一下命名空间的名称解析规则做为这三篇系列文章的结束. 全局空间 ...
- Docker系列(8)- 常用其他命令(1) | 日志、元数据、进程的查看
后台启动容器 # 命令 docker run -d 镜像名 [root@localhost ~]# docker run -d centos #问题:docker ps,发现centos停止了 #常见 ...
- disruptor笔记之二:Disruptor类分析
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- DevOps与CICD简介
整体知识点 ·Devops与CI/CD简介 ·Gitlab安装与Git命令使用 ·Gitlab实现持续集成 ·Gitlab实现分支管理 ·Jenkins简介及安装 ·Jenkins插件管理及基础配置 ...
- css布局宽度自适应
随着各种终端的不断涌现,网页中的元素适应不同的分辨率变得特别重要,根据经验,涉及到宽度自适应的一共有四种情况: 左端固定,右边自适应:右端固定,左边自适应:两端固定,中间自适应:中间固定,两端自适应. ...
- GDOI 2021 退役记
Day -n 时常想自己不学OI会怎样,经常畏惧自己其实没有心里想的那样有能力,去机房来麻痹自己 从 3.21 始加大频率刷题,复习以前都学会,而现在都被抛在脑后的算法 反正都要退役了,成绩也得鲜亮点 ...
- Redis之品鉴之旅(一)
Redis之品鉴之旅(一) 好知识就如好酒,需要我们坐下来,静静的慢慢的去品鉴.Redis作为主流nosql数据库,在提升性能的方面是不可或缺的.下面就拿好小板凳,我们慢慢的来一一品鉴. 1)redi ...
- Windows10系统下Java JDK下载、安装与环境变量配置(全网最全步骤)
1.首先要明确: JDK.JRE.JVM的含义 2.下载目前最新的JDK:Java SE Development Kit 17,传送门::https://www.oracle.com/java/tec ...
- JUC之Executor,ExecutorService接口,AbstractExecutorService类
java多线程的Executor中定义了一个execut方法,ExecutorService接口继承了Executor接口,并进行了功能的扩展组合,定义了shutdown,shutdownNow,su ...