前言
当一个构造函数返回一个根本类型的话很好写,指定重定向原型对象和this指向,然而还有两种状况,比方返回一个堆(函数或者对象),那么new进去的实例就会扭转,如下代码
function Dog(name){ this.name = name // 在构造函数中 return 根本类型的成果和没有写 return 是一样的 // return 123 // 在构造函数中 return 一个对象,那么最终 new 进去的是本人写的对象 //return {age:100} // 在构造函数中 return 一个函数,那么最终 new 进去的是本人写的函数 return function(){ console.log('fn......') } // 在构造函数中 return null 的成果和没有写 return 是一样的 return null}let wc = new Dog('wangcai')
第一版 依据 new 本人写一个 _new()
function Dog(name){ this.name = name}// ===============================================(第一版)function _new(Ctor, ...args){ let obj = {}; obj.__proto__ = Ctor.protoType; Ctor.apply(obj,args) return obj}let wc = _new(Dog, 'wangcai')console.log(wc.name) // wangcai
第二版 (应用Object.create() 办法实现 )优化代码; 然而有一个问题 如果 传的参数不是一个狗造函数,在调用_new() 的时候会报错
function Dog(name){ this.name = name}// ===============================================(第二版)function _new(Ctor, ...args){ let obj = Object.create(Cror.perototype) Ctor.apply(obj,args) return obj}// 正确调用let wc = _new(Dog, 'wangcai')// 如果这样写会报错let wc = _new('hellow', 'wangcai')console.log(wc.name) // wangcai
第三版 这边能够做一个判断 因为咱们都晓得 结构器上都有一个属性 ’perototype‘ 咱们能够依据这个属性进行判断
function Dog(name){ this.name = name}// ===============================================(第三版)function _new(Ctor, ...args){ if(Ctor.hasOwnProperty('perototype')){ throw new TypeError(`${Ctor} is not a constructor`) } let obj = Object.create(Cror.perototype) Ctor.apply(obj,args) return obj}// 正确调用let wc = _new(Dog, 'wangcai')// 如果这样写会报错let wc = _new('hellow', 'wangcai') // console.log(wc.name) // wangcai
以上却是是能够 然而 依据前言局部的状况,还是会呈现问题,达不到new的成果,所一有了第四版
第四版
function Dog(name){ this.name = name}// ===============================================(第四版)function _new(Ctor, ...args){ if(Ctor.hasOwnProperty('perototype')){ throw new TypeError(`${Ctor} is not a constructor`) } let obj = Object.create(Cror.perototype) let result = Ctor.apply(obj,args) if(result !== null && (typeof result == 'object' || typeof result == 'function')){ return result } return obj}// 正确调用let wc = _new(Dog, 'wangcai')// 如果这样写会报错let wc = _new('hellow', 'wangcai') // console.log(wc.name) // wangcai