面向对象练习题(重写内置new)

107 阅读1分钟

步骤: (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;
    };
}