步骤: (1)创建一个实例对象:创建一个空对象,让其__proto__指向Ctor.prototype
(2)把构造函数当作普通的函数执行,并且让函数中的THIS指向创建的实例对象
(3)根据构造函数的返回结果,判断我们最后返回的是实例对象还是自己的返回值 如果是引用类型,返回这个引用类型,否则返回我们新创建的实例对象
1、简单版本(不考虑兼容)
2、处理__proto__
function _new(Ctor, ...params) {
let obj = Object.create(Ctor.prototype);
let result = Ctor.call(obj, ...params);
if (/^(object|function)$/.test(typeof result)) return result;
return obj;
}
3、处理...params
function _new(Ctor) {
var params = [].slice.call(arguments, 1),
obj = Object.create(Ctor.prototype),
result;
result = Ctor.apply(obj, params);
if (/^(object|function)$/.test(typeof result)) return result;
return obj;
}
4、加上校验参数规则
function _new(Ctor) {
var reg = /^(object|function)$/i,
params,
obj,
result;
if (typeof Ctor !== "function" || !reg.test(typeof Ctor.prototype)) throw new TypeError('Ctor is not a constructor');
params = [].slice.call(arguments, 1);
obj = Object.create(Ctor.prototype);
result = Ctor.apply(obj, params);
if (reg.test(typeof result)) return result;
return obj;
}
5、Object.create(IE6、7、8不兼容)
(1)Object.create([prototype]):创建一个空对象,并且让对象的__proto__指向[prototype](把[prototype]作为创建空对象的原型)
(2)let obj = Object.create(10); //=>Uncaught TypeError: Object prototype may only be an Object or null 只能传递对象或者null才可以
(3)let obj = Object.create(null); //=>创建了一个非任何类实例的空对象(它没有__proto__)「可以被理解为纯粹的对象」
6、重写Object.create()
if (!Object.create) {
// IE 6~8
Object.create = function create(prototype) {
if (!/^(object|function)$/i.test(typeof prototype)) throw new TypeError('Object prototype may only be an Object or null');
function proxy() {}
proxy.prototype = prototype;
return new proxy;
};
}