乐趣区

关于javascript:手写一个-new

前言

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