手写实现JS中的new

目录
  • 1 new 运算符简介
  • 2 new 究竟干了什么事
  • 3 模拟实现 new 运算符
  • 4 补充

⚠ 预备知识:

  • 了解原型和原型链
  • 了解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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C# Newtonsoft.Json 解析多嵌套json 进行反序列化的实例

    我就废话不多说啦,大家还是直接看代码吧~ [ { "orderNo": "3213123123123", "time": "2016-09-09 12:23:33", "orderStatus": "1", "freeShipping": true, "fullCut": 20, "originalCost": 340, &qu

  • c# Newtonsoft.Json 常用方法总结

    1 实体类的 Json 序列化和反序列化 我们以如下的 Person 类举例,其中包含了常用的数据类型: public class Person { public int ID { get; set; } public string Name { get; set; } public DateTime Birthday { get; set; } public bool IsVIP { get; set; } public float Account { get; set; } public s

  • c#添加Newtonsoft.Json包的操作

    C#使用json 点击工具 - NuGet包管理器 - 程序包管理控制台,输入下面命令: Install-Package Newtonsoft.Json 即可使用Newtonsoft.Json 包进行json操作 PM> Install-Package Newtonsoft.Json 正在尝试收集与目标为".NETFramework,Version=v4.0"的项目"QiniuTests"有关的包"Newtonsoft.Json.11.0.2&quo

  • JavaScript中new操作符的原理示例详解

    new的用处 new的作用是通过构造函数来创建一个实例对象,该实例与原型和构造函数之间的关系如下图所示: 先来总结一下 创建一个空对象 空对象的内部属性 __proto__ 赋值为构造函数的 prototype 属性 将构造函数的 this 指向空对象 执行构造函数内部代码 返回该新对象 详细说明 执行 new 操作时会依次经过以下步骤: 1.创建一个空对象 空对象是 Object 的实例,即 {} . let obj = {} 2.空对象的内部属性 __proto__ 赋值为构造函数的 pro

  • 深入聊一聊JS中new的原理与实现

    定义 new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例. 使用new [constructor]的方式来创建一个对象实例,但构造函数的差异会导致创建的实例不同. 构造函数体不同 构造函数也是函数,其唯一的区别就是调用方式不同,任何函数只要使用 new 操作符调用就是构造函数,而不使用 new 操作符调用的函数就是普通函数. 因此构造函数也可以带有返回值,但是这会导致new的结果不同. 无返回值 function Person(name) { this.name = n

  • JS 中 new 的作用详细

    目录 1.举例 2.制造一百个士兵 3.质疑 4.改进 5.优雅? 6.JS 之父的关怀 7.这一次我们用 new 来写 8.注意 constructor 属性 简介: 大部分讲 new 的文章会从面向对象的思路讲起,但是我始终认为,在解释一个事物的时候,不应该引入另一个更复杂的事物. 想象我们在制作一个策略类战争游戏,玩家可以操作一堆士兵攻击敌方. 我们着重来研究一下这个游戏里面的「制造士兵」环节. 一个士兵的在计算机里就是一堆属性,如下图: 1.举例 我们只需要这样就可以制造一个士兵: va

  • 如何自己实现JavaScript的new操作符

    构造函数 在介绍new之前,必须要知道什么是构造函数. 构造函数和普通函数在写法上没有任何区别,当一个函数通过new Fun()调用时,就叫做构造函数,构造函数首字母通常大写. function User(name) { this.name = name; } let u = new User('leo'); 这里,User就是构造函数,当然你也可以直接调用User(),但是这样就起不到创建实例的作用,在非严格模式下,会把name属性挂在window上. new 操作符 那么new操作符到底做了

  • JavaScript中实现new的两种方式引发的探究

    前言 当你 new 一个构造函数时发生了什么? "众所周知"的三步: 创建一个空对象,将它的引用赋给 this,继承函数的原型:通过 this 将属性和方法添加至这个对象:最后返回 this 指向的新对象,也就是实例. 一般来说在js中大概是这样的: function Mynew(parent,...rest){ let obj={}; obj.__proto__=parent.prototype; let res=parent.apply(obj,rest); return type

  • 关于Js中new操作符的作用详解

    前言 Js是当今时代最常用的代码操作语言,其中new操作符尤为常见.对于很多代码小白来说,并不清楚new在Js中扮演着怎样的角色,具体是做什么用,干了什么.本文从new操作符的作用着手,简单介绍new操作符相关知识. 什么是new? 众所周知,在JS中,new的作用是通过构造函数来创建一个实例对象. 像下面这样:(和普通函数不一样,当函数用作构造函数时,首字母一般要大写,以作区分.) function Foo(name) { this.name = name; } console.log("ne

  • JavaScript中的 new 命令

    面向对象编程(Object Oriented Programming,缩写为 OOP)是目前主流的编程范式. 那么,"对象"(object)到底是什么? 对象是单个实物的抽象. 对象是一个容器,封装了属性(property)和方法(method). 属性是对象的状态,方法是对象的行为(完成某种任务). 2. 构造函数 面向对象编程的第一步,就是要生成对象.通常需要一个模板,表示某一类实物的共同特征,然后对象根据这个模板生成. JavaScript 语言使用构造函数(constructo

随机推荐