new内部工作流程:
- 检测 new 的目标是不是非函数,如果是非函数,抛出错误
- 修改 new 的 target 属性,使之指向构造函数
- 新建一个空的实例对象。注意不能使用
Object.create 创建,否则当构造函数原型为 null 的时候,实例对象隐式原型也为 null,但根据 new 的规范,这里不是这样的。
- 检测构造函数原型是否为
null,如果不是,则将其作为实例对象的隐式原型,否则将 Object 的原型作为实例对象的隐式原型
- 执行构造函数,将其 this 指向实例对象,同时传入参数
- 获得构造函数返回值,判断是不是对象,如果是对象,则作为 new 的返回值,否则将实例对象作为 new 的返回值
function myNew(Fn,...args){
if(typeof Fn != 'function'){
throw new TypeError(Fn + 'is not a constructor')
}
myNew.target = Fn
const instance = {}
instance.__proto__ = Fn.prototype instanceof Object ? Fn.prototype : Object.prototype
const returnValue = Fn.call(instance,...args)
return returnValue instanceof Object ? returnValue : instance
}