【手撕系列】new

简介: new

9616c9d877dde168531ba1f6e78d0ef.png

前言

new 运算符是 javascript 中常用的一个方法,经常用来创建我们自定义对象或者内置对象实例,今天就和大家一起了解和动手写一个自己的 new 方法 (create)

Javascript 中的 new

new 运算符 创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例

手撕代码前还是先来了解下 new 究竟是个什么东西,看了上面的定义,可能有的同学还是有点蒙,简单总结下 new 就是用来 创造实例对象的一个方法

本质上它也是一个方法,接收了两个参数 constructor(指定对象实例的类型的类或函数)arguments(调用的参数列表) ,怎么样,用过 es6 的 class 方法的同学是不是觉得很熟悉,我们来对比下

new constructor[([arguments])]  // 注:文档中要是看到中括号表示可选项
class Name {
    constructor([arguments]) {}
}
new Name()
复制代码

实际上 new 一个 class 的作用和 new 一个 function 是一样的,都是通过一个构造函数 constructor 来创建一个实例对象,它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法

new 操作符做了什么?

要想手写一个 new ,那就要知道 new 都做了哪些操作

  • 创建了一个空对象({}
  • 为创建的空对象添加属性 __ptoto__ ,并指向于构造函数的原型
  • 将创建的对象作为构造函数的上下文 (改变this指向)
  • 如果该函数没有返回对象,则返回 this

注意这里是没有返回对象,如果返回的是一个基础数据类型,则忽略

如何手写一个 new 方法?

我们先用 new 方法通过构造函数实例化一个对象,看看究竟发生了什么,然后在自己定义一个 create 方法,最后看结果一不一致

编写构造函数

function Friend(name) {
    this.name = name
}
复制代码

通过 new 来实例化对象

const friend = new Friend('小明')
console.log(friend)
复制代码

当代码 new Friend(...) 执行时,会发生

  • 一个继承自 Friend.prototype 的对象被创建
  • this 绑定到创建的对象
  • 返回该对象

create 的实现

function create (fn, ...args) {
    // 1. 创建一个空对象
    var obj = {}
    // 2. 将空对象的原型指向构造函数的原型
    Object.setPrototypeOf(obj, fn.prototype)
    // 3. 将空对象作为构造函数的上下文
    var result = fn.apply(obj, args)
    // 4. 对构造函数的返回值做判断处理
    return result instanceof Object ? result : obj
}
复制代码

最后我们来试一下

const friend1 = create(Friend, '小明')
console.log(friend)  // Friend {name: '小明'}
console.log(friend1) // Friend {name: '小明'}
console.log(friend1.__proto__ == friend.__proto__) // true
复制代码

好啦~大功告成 ^-^

相关文章
|
存储 算法 数据处理
手撕学生管理系统超详解——【c++】
该程序的目标是提供一个简单且易于使用的学生成绩管理工具,以便教育机构能够有效地录入、修改、查询和排序学生的成绩信息。通过将学生信息保存到文件中,确保数据的持久性,即使在程序关闭后,学生成绩数据也能够被保留和恢复。
157 0
|
6月前
|
存储 Go 调度
听说90%的人都没搞定手撕协程池这道面试题!
听说90%的人都没搞定手撕协程池这道面试题!
|
6月前
|
搜索推荐
手撕各种排序(中)
手撕各种排序(中)
65 0
|
6月前
|
算法 搜索推荐 索引
手撕各种排序(下)
手撕各种排序(下)
59 0
|
6月前
|
安全 Java C语言
手撕各种排序(上)
手撕各种排序
50 0
|
11月前
手撕面试题
手撕面试题
|
C语言
深夜手撕三角
深夜手撕三角
33 0
|
缓存 调度
手撕代码系列(四)
手撕代码系列(四)