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