预备知识:

  1. 了解原型和原型链
  2. 了解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()为例,当它执行时,会发生以下事情:

  1. 创建一个空的简单JS对象

    const obj = {}
  2. 给这个对象添加属性__proto__,并将该属性链接到构造函数的原型对象

    obj.__proto__ = Person.prototype
  3. 调用构造函数Person,并将this绑定到新创建的对象obj

    Person.apply(obj)
  4. 如果构造函数没有显式返回一个对象,则返回新创建的对象,即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 补充

  1. ES5提供了Object.create方法,该方法可以创建一个对象,并让新对象的__proto__属性指向已经存在的对象。

    所以我们可以使用这个方法合并1、2两步

    const obj = Object.create(constructor.prototype)
    // 等价于
    const obj = {}
    obj.__proto__ = constructor.prototype
  2. 对于第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
  3. 注意,模拟实现的函数_new传入的参数只能是构造函数,不能是类

    class Animal {  ...}_new(Animal)// 会报错:Class constructor Animal cannot be invoked without 'new'// 类只能通过new来创建实例

公众号【前端嘛】获取更多优质内容

面试官:熟悉JS中的new吗?能手写实现吗?的更多相关文章

  1. 面试官:Redis中字符串的内部实现方式是什么?

    在面试间里等候时,感觉这可真暖和呀,我那冰冷的出租屋还得盖两层被子才能睡着.正要把外套脱下来,我突然听到了门外的脚步声,随即门被打开,穿着干净满脸清秀的青年走了进来,一股男士香水的淡香扑面而来. 面试 ...

  2. 面试官:Redis中哈希数据类型的内部实现方式是什么?

    面试官:Redis中基本的数据类型有哪些? 我:Redis的基本数据类型有:字符串(string).哈希(hash).列表(list).集合(set).有序集合(zset). 面试官:哈希数据类型的内 ...

  3. 面试官:Redis中集合数据类型的内部实现方式是什么?

    虽然已经是阳春三月,但骑着共享单车骑了这么远,还有有点冷的.我搓了搓的被冻的麻木的手,对着前台的小姐姐说:"您好,我是来面试的."小姐姐问:"您好,您叫什么名字?&quo ...

  4. 面试官:Redis中有序集合的内部实现方式是什么?

    面试官:Redis中基本的数据类型有哪些? 我:Redis的基本数据类型有:字符串(string).哈希(hash).列表(list).集合(set).有序集合(zset). 面试官:有序集合的内部实 ...

  5. 【高并发】面试官:Java中提供了synchronized,为什么还要提供Lock呢?

    写在前面 在Java中提供了synchronized关键字来保证只有一个线程能够访问同步代码块.既然已经提供了synchronized关键字,那为何在Java的SDK包中,还会提供Lock接口呢?这是 ...

  6. 【性能优化】面试官:Java中的对象都是在堆上分配的吗?

    写在前面 从开始学习Java的时候,我们就接触了这样一种观点:Java中的对象是在堆上创建的,对象的引用是放在栈里的,那这个观点就真的是正确的吗?如果是正确的,那么,面试官为啥会问:"Jav ...

  7. 面试官:Redis中列表的内部实现方式是什么?

    在面试间里等候时,感觉这可真暖和呀,我那冰冷的出租屋还得盖两层被子才能睡着.正要把外套脱下来,我突然听到了门外的脚步声,随即门被打开,一位眉毛弯弯嘴唇红红的小姐姐走了进来,甜甜的香水味立刻钻进了我的鼻 ...

  8. 面试官:Java中对象都存放在堆中吗?你知道逃逸分析?

    面试官:Java虚拟机的内存分为哪几个区域? 我(微笑着):程序计数器.虚拟机栈.本地方法栈.堆.方法区 面试官:对象一般存放在哪个区域? 我:堆. 面试官:对象都存放在堆中吗? 我:是的. 面试官: ...

  9. 面试官:Zookeeper怎么解决读写、双写并发不一致问题,以及共享锁的实现原理?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 今天清明假期,赶上北京玉渊潭公园 ...

随机推荐

  1. ecshop二次开发秒杀、限时折扣、清仓等功能

    限时抢购,秒杀商品的二次开发 1,先在后台admin/templates 中找goods_info.htm文件到促销部分,改为一个下拉列表的分别是促销,限时,秒杀,值分别是1,2,3这样,代码如下: ...

  2. 一朵云、一张网、一体化 ——GRTN 打造最佳流媒体场景实践

    阿里巴巴 GRTN 是面向流媒体云原生设计的,方便客户构建自己的流媒体云原生应用,让流媒体服务无处不在. 在近期召开的分布式云主题报告会上,阿里云资深技术专家卢日发表了题为<GRTN 打造阿里云 ...

  3. modern php closure 闭包

    * 在array_map()函数中使用闭包 <?php $numbersPlusOne = array_map(function($number) { return $number + 1; } ...

  4. ActiveQq的代码实现

    ]从java代码开始再过渡到springboot Java代码的实现 1.activemq这个消息中间件有两种形式 1. p2p(生产者,消费者) 特点: 生产者: package com.lqh; ...

  5. 远程连接centos7中mysql8.0

    远程连接centos7中mysql8.0 1.使用Navicat for MySQL或者其它数据连接软件 2.先检查centos中防火墙是否关闭,如果关闭不需要设置,如果没有关闭防火墙,请打开3306 ...

  6. Win10删除电脑3D对象等7个文件夹

    把下面几个注册表项依次删除掉 "图片"文件夹:[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Expl ...

  7. python3之工程中必须依赖的__init__.py

    1.  __init__.py 1.1  什么是__init__.py 在Python3工程里,当python3检测到一个目录下存在__init__.py文件时,Python3就会把它当成一个模块(m ...

  8. centos6.5 oracle 卸载

    1.使用SQL*PLUS停止数据库 [oracle@OracleTest oracle]$ sqlplus / as sysdba SQL> shutdown immediate; SQL> ...

  9. ThreadLocal概念以及使用场景

    ThreadLocal概念以及使用场景 根据自身的知识深度,这里只限于自己使用和学习的知识点整理,原理的解释还需要再沉淀. 该文章从项目开发中举例,希望能帮助到各位,不了解ThreadLocal的朋友 ...

  10. python中冒泡排序代码实现

    1.冒泡排序代码如下图: #冒泡算法l=[12,4,56,10,6,2]for i in range(0,6): for j in range(i+1,6): if l[i]>l[j]: a=l ...