likes
comments
collection
share

手写 New 方法

作者站长头像
站长
· 阅读数 5

不熟悉原型 与 原型链的小伙伴建议看一下这篇文章,写的很好,替作者宣传一波

首先,我们来思考 New 关键字 都做了哪些事情

    1. 创建了一个全新的对象
    let obj = Object.create(null);
    1. 将新生成的对象 比如 obj 对象,将 对象实例通过__proto__ 原型链 挂载到对应类的原型对象上, 如下图所示,借用了上面讲解原型链作者的图片

手写 New 方法

基于对链表的理解我们可以写出如下两行代码

    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);
    1. 返回这个对象,注意:如果返回的对象 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);