深入之new的模拟实现

2019-07-12  本文已影响0人  明里人

定义一个构造函数

function Person(a,b,c){
  this.a = a;
  this.b = b;
  Person.prototype.c = c;
}

实现方法一:通过new1(obj,arguments)使用new

function new1(func){
    //new 出的实例对象 __ proto__ 指向构造函数的原型,Object.create创建的对象的__proto__默认指向create方法里的参数
    //用于获取构造函数原型上的成员
    let newObj = Object.create(func.prototype);
    //将arguments转为数组,并截取传递的参数,将构造函数指向新对象
    //考虑到func构造函数可能会有return返回值,使用returnObj接收
    let returnObj = func.apply(newObj,Array.prototype.slice.call(arguments,1));
    // 如果构造函数有return值,并且返回值类型是 object 或者 function,则返回构造函数return的结果
    if((typeof returnObj === 'object' || typeof returnObj === 'function') && returnObj !== null){
        return returnObj;
    }
    return newObj; // 否则返回新创建的实例对象。(一般构造函数中不会进行return,主要是生成新的实例对象)
} 
let obj = new1(Person,1,2,3);
console.log(obj.a);  // 1
console.log(obj.c);  // 3
console.log(obj.__proto__ === Person.prototype); // true

实现方法二:通过 new2 (Person)(1,2,3) 使用new

function new2(func){
    return function(){
        let newObj = {};
        if(func.prototype !== null){
            //将__proto__指向构造函数原型,用于获取原型上的成员
            newObj.__proto__ = func.prototype;
        }
        let returnObj = func.apply(newObj,arguments);
        if((typeof returnObj === 'object' || typeof returnObj === 'function') && returnObj !== null){
            return returnObj;
        }
        return newObj;
    }
}
let obj = new2(Person)(1,2,3);
console.log(obj.a);  // 1
console.log(obj.c);  // 3
console.log(obj.__proto__ === Person.prototype); // true
上一篇下一篇

猜你喜欢

热点阅读