前言

当一个构造函数返回一个根本类型的话很好写,指定重定向原型对象和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