手写 New 方法
不熟悉原型 与 原型链的小伙伴建议看一下这篇文章,写的很好,替作者宣传一波
首先,我们来思考 New
关键字 都做了哪些事情
-
- 创建了一个全新的对象
let obj = Object.create(null);
-
- 将新生成的对象 比如 obj 对象,将 对象实例通过
__proto__
原型链 挂载到对应类的原型对象上, 如下图所示,借用了上面讲解原型链作者的图片
- 将新生成的对象 比如 obj 对象,将 对象实例通过
基于对链表的理解我们可以写出如下两行代码
obj.__proto__ = classRef.prototype;
obj.__proto__.constructor = classRef;
事实上只需要通过 obj.__proto__ = classRef.prototype
就可以将链给挂上去了
- 3.接下来通过 apply 方法改变 this 指向, 使通过new 创建的对象最终都会被 [[Prototype]] 链接到这个函数的 prototype 对象上
const res = obj.__proto__.constructor.call(obj, ...args);
-
- 返回这个对象,
注意:如果返回的对象 res 不是对象类型, 那么 new 表达式中的函数会被调用自动返回这个新的对象
- 返回这个对象,
return typeof res === 'object' ? res || obj : obj;
完整代码如下
function MyNewInstance (classRef, ...args) {
let obj = Object.create(null);
obj.__proto__ = classRef.prototype;
const res = obj.__proto__.constructor.call(obj, ...args);
// 简单点也可以写出 const res = classRef.call(obj, ...args);
return typeof res === 'object' ? res || obj : obj;
}
测试如下:
function Father(age) {
this.age = age;
}
const fatherInstance = MyNewInstance(Father, 10);
const fatherInstance2 = new Father(10);
转载自:https://juejin.cn/post/7355303183923593279