JavaScript new 一个对象的过程

169 阅读1分钟

“要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它” --摘自《JavaScript设计模式与开发实践》 我们先来如何用new运算符从构造器中得到一个对象

function Super(opts = {}) {
    this.hobby = opts.hobby;
}

Super.prototype.printHobby = function () {
    console.log(this.hobby);
};

let instance = new Super({ hobby: 'football' });
instance.printHobby();

虽然上述代码是通过 new Super() 调用的,但是我们知道 JS 是没有类的概念的,当使用 new 运算符来调用函数时其实就是对函数的构造调用。 下面我们来看看 new 一个构造函数的过程是怎样的

/**
 * 1.在内存中创建一个新对象
 * 2.这个新对象内部的[[Prototype]]特性被赋值为构造函数的prototype属性
 * 3.构造函数内部的this被赋值为这个新对象(即this指向新对象)
 * 4.执行构造函数内部的代码(给新对象添加属性)
 * 5.如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象
 **/
    
function objectFactory(...args) {
    let obj = {};
    const constructor = args.shift();
    obj.__proto__ = constructor.prototype;
    const res = constructor.apply(obj, args);
    return (res !== null && typeof res === 'object') ? res : obj;
}

function Super(opt = {}) {
    this.hobby = opt.hobby;
}

Super.prototype.printHobby = function () {
    console.log(this.hobby);
};

let instance = objectFactory(Super, { hobby: 'football' });
instance.printHobby();

下图是在 chrome 打出的结果,这两段代码得出的结果是一样的

截屏2023-07-13 10.19.11.png