面试官:熟悉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怎么解决读写、双写并发不一致问题,以及共享锁的实现原理?
哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 今天清明假期,赶上北京玉渊潭公园 ...
随机推荐
- Kubernetes-Pod介绍(三)-Pod调度
前言 本篇是Kubernetes第六篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战. Kubernetes系列文章: Kubernetes介绍 Kubernetes环境搭建 Kuberne ...
- PHP设计模式之模板方法模式
模板方法模式,也是我们经常会在不经意间有会用到的模式之一.这个模式是对继承的最好诠释.当子类中有重复的动作时,将他们提取出来,放在父类中进行统一的处理,这就是模板方法模式的最简单通俗的解释.就像我们平 ...
- jquery监听动态添加的input的change事件
使用下面方法在监听普通的input的change事件正常 $('#pp').on('change', 'input.videos_poster_input', function () { consol ...
- Java基础系列(10)- 类型转换
类型转换 由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换.运算中,不同类型的数据先转换为同一类型,然后进行运算. 低 ------------------------------ ...
- 总结了下PHPExcel官方读取的几个例子
1.使用 PHPExcel_IOFactory 读取文件 $objPHPExcel = PHPExcel_IOFactory::load($inputFileName); 2.使用一个特定的读取类,读 ...
- JDK原生反序列化利用链7u21
前言 JDK 7u21以前只粗略的扫过一眼,一看使用了AnnotationInvocationHandler,就以为还是和 CC1 一样差不多的利用方式,但最近仔细看了下利用链发现事情并不简单- 7u ...
- Ubuntu解决安装没有候选
Ubuntu解决安装没有候选 很多初次上手的小白们最头疼的可能就是一下这种问题了 这是我也载过很多次的坑,原因是软件安装源的问题,需要去软件安装设置里更改合适的源 结局方案如下:(具体操作) 有个So ...
- SpringBoot碰到的疑问或问题
1.@ResponseBody 和 @RequestBody 的区别 @ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response ...
- 查看显卡报错:NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
当输入nvidia-smi时出现 NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make ...
- PowerDotNet平台化软件架构设计与实现系列(02):数据库管理平台
为了DB复用和简化管理,我们对常见应用依赖的DB模块进行更高级的提取和抽象. 虽然一些ORM可以简化DB开发,但是我们还是需要进行改进和优化,否则应用越多,后期管理运维越混乱. 根据常见开发需要,数据 ...