//首先来一个例子 function person(name,age) { this.name = name; this.age = age; } person.prototype.getName = function(){ return 1 } let boy = new person('lin','18');
此时我们打印boy
1. 我们会发现他的类型是object,所以new第一件干的事就是新建了一个空对象(obj)
function myNew(){ let obj = {} }
但我们发现boy并不是一个空对象,它继承了person的原型方法getName.
2.所以new第二件干的事就是将空对象(obj)的原型链指向了构造函数的原型。
function myNew(fn) { let obj = {}; Object.setPrototypeOf(obj,fn.prototype); }
3.但boy中还含有person的参数(如name,age),所以第三件事将对象绑定在构造函数上
function myNew(fn, ...args) { let obj = {}; Object.setPrototypeOf(obj,fn.prototype); fn.call(obj, ...args); }
4.最后判断函数的返回值类型是否为objcet,如果返回值是对象,则使用返回值,不为对象则返回obj
function myNew(fn,...args){ let obj = {}; obj._proto_ = fn.prototype; let res = fn.call(obj,...args); return typeof res === 'object' ? res : obj }
最后检验
let girl = myNew(person, 'nv', '18');
console.log(girl)
console.log(girl.getName())
成功
总结:new分别做了这几件事
1.新建一个空对象
2.将对象的原型链指向构造函数的原型
3.讲对象绑定在构造函数上
4.根据函数的返回值类型,返回结果