手写new函数

143 阅读1分钟

new函数作用

要想知道new函数怎么实现,首先要清楚new函数的功能。

  1. 首先是新建一个函数
  2. 这个新函数的 prototype 指向构造函数的 prototype属性
  3. 构造函数内部的this指向新函数
  4. 为新对象添加属性
  5. 返回这个新对象 es6为new函数添加了target属性,允许你检测函数或构造方法是否是通过new方式被调用的。new.target返回一个指向构造方法或函数的引用.

实现代码

// 实现方法
function myNew () {
    // 获取传入的函数
    let constructor = arguments[0];
    if (typeof constructor !== 'function') {
        throw ('第一个参数必须为function类型!');
    }
    // new.target指向这个函数
    myNew.target = constructor;
    // 获取函数外的其他参数
    let args = [].slice.call(arguments, 1);
    // let obj = {};
    // obj.__proto__ = constructor.prototype;
    // 1.新建一个函数
    // 2.这个新对象内部的 [[Prototype]] 指针被赋值为构造函数(constructor)的 prototype 属性
    let obj = Object.create(constructor.prototype);
    // 3. 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)
    // 4. 执行构造函数内部的代码(给新对象添加属性)
    let res = constructor.apply(obj, args);
    // 5. 如果构造函数返回非空对象,则返回该对象;否则,返回刚才创建的新对象
    if (res !== null && (typeof res === 'object' || typeof res === 'function')) {
        return res;
    }
    return obj;
}


// 测试方法
function person (name, age) {
    // console.log('this:', this);
    // console.log('new.target:', new.target);
    // console.log('useNewOperator.target:', myNew.target);
    this.name = name;
    this.age = age;
}
person.prototype.sayName = function () {
    console.log(this.name);
};
const p1 = new person('new', 20);
console.log(p1, p1.target);
p1.sayName();

const p2 = myNew(person, 'zhang', 18);
console.log(p2, p2.target);
p2.sayName();