function _new(fn,...args){
if(typeof fn !== 'function'){
throw '“fn” must be a function'
}
let obj = new Object();
obj.__proto__ = Object.create(fn.prototype)
let result = fn.apply(obj,args)
let isObject = typeof result === 'object' && typeof result !== null
let isFunction = typeof result === 'function'
return isObject || isFunction ? result : obj
}
function Person(name){
this.name = name
}
_new(Person,'Mike')
//Person{name: 'Mike'}
_new(String, 111)
//String{}
new String(111)
//String{'111'}
_new方法无法正确实例化String对象, 原因是什么呢?
###因为String支持函数直接调用,String(111)
它会对参数进行类型转换,返回一个字面量,而new String(111)
是返回一个字符串对象,这两个行为是不一样的。而我们通常自定义一个构造函数时并没有做这样的区分,认为一定会被new
所执行的,所以才会有this.xxx这一系列操作。而自己实现的new函数实际上是借用了js里函数执行可以指定this的行为,所以不需要真正new操作符也能构造出实例。如果这个构造函数也和String这些内置构造器一样做区分的话那即使是自定义的也一样得不到同样结果