new操作符到底做了什么?
简单来说:
创建一个空对象
let emptyObj = {}
链接空对象的对象原型和构造函数的原型对象
emptyObj.__proto__ = Constructor.prototype
使用apply改变this指向,使this指向创建的空对象并执行构造函数
let result = Constructor.apply(newObject, args);
返回构造函数的返回值 或 返回这个空对象(根据构造函数返回值类型决定)
return result
or
return emptyObj
自己手写一个new操作函数
//自己写一个 new 操作符的函数
function myNew(Constructor, ...args) {
// 判断Constructor参数是否是函数
if (typeof Constructor !== 'function')
return 'Constructor.apply is not a function';
// 1、创建了一个全新的空对象。
let newObject = {};
// 2、将对象原型链接到这个函数的prototype原型对象上,以链接上构造函数的原型链,完成原型的继承。
newObject.__proto__ = Constructor.prototype;
// 此处是把 1 / 2 步结合到一起
// const newObject = Object.create(Constructor.prototype);
// 3、执行构造函数,
// 并将调用者设置为 newObject,这样在执行构造函数时,this就指向 newObject,参数是args
// 构造函数的返回值赋值给 result
let result = Constructor.apply(newObject, args);
// 4. 判断构造函数执行返回的结果是否是 引用数据类型,
// 若是则返回构造函数执行的结果,否则返回创建的对象。
if ((result !== null && typeof result === 'object') || (typeof result === 'function')){
return result;
}
else{
return newObject;
}
//new 操作符执行完毕
};