ChatGPT 可用网址,仅供交流学习使用,如对您有所帮助,请收藏并推荐给需要的朋友。
https://ckai.xyz
前言
当一个构造函数返回一个基本类型的话很好写,指定重定向原型对象和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