关于构造函数new执行的过程和重写内置new

要执行的代码

function Dog(name) {
    this.name = name;
}
Dog.prototype.bark = function () {
    console.log('wangwang');
}
Dog.prototype.sayName = function () {
    console.log('my name is ' + this.name);
}
let sanmao = _new(Dog, '三毛');
sanmao.bark(); //=>"wangwang"
sanmao.sayName(); //=>"my name is 三毛"
console.log(sanmao instanceof Dog); //=>true */

第一种new创建的过程代码执行:

// Ctor -> constructor缩写 构造函数
// params -> 后期给Ctor传递的所有的实参信息

function _new(Ctor, ...params) {
    // 1.创建Ctor的一个实例对象 
    // 实例.__proto__===Ctor.prototype
    let obj = {};
    obj.__proto__ = Ctor.prototype;

    // 2.把构造函数当做普通函数执行「让方法中的THIS->实例对象」
    let result = Ctor.call(obj, ...params);

    // 3.确认方法执行的返回值「如果没有返回值或者返回的是原始值,我们让其默认返回实例对象即可...」
    if (result !== null && /^(object|function)$/.test(typeof result)) return result;
    return obj;
} 

优化版本:

function _new(Ctor, ...params) {
    let obj,
        result,
        proto = Ctor.prototype,
        ct = typeof Ctor;
    // 校验规则
    if (Ctor === Symbol || Ctor === BigInt || ct !== 'function' || !proto) throw new TypeError(`${Ctor} is not a constuctor!`);
    obj = Object.create(Ctor.prototype);
    result = Ctor.call(obj, ...params);
    if (result !== null && /^(object|function)$/.test(typeof result)) return result;
    return obj;
}

Object.create([obj])解释:

Object.create([obj]):创建一个空对象,并且让空对象.proto指向[obj] “把[obj]作为新实例对象的原型”

  • [obj]可以是一个对象或者是null,但是不能是其他的值
  • Object.create(null) 创建一个不具备proto属性的对象「不是任何类的实例」

面试题:

// 面试题:重写Object.create()
Object.create = function create(prototype) {
    if (prototype !== null && typeof prototype !== "object") throw new TypeError('Object prototype may only be an Object or null');
    var Proxy = function Proxy() {}
    Proxy.prototype = prototype;
    return new Proxy;
};

你可能感兴趣的:(关于构造函数new执行的过程和重写内置new)