前言
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 复制代码
好啦~大功告成 ^-^