手写一个 new

loong / 153 /

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

作者
loong
许可协议
CC BY 4.0
发布于
2023-08-27
修改于
2024-12-22
Bonnie image
尚未登录