new内部的执行顺序:

  • 先构建一个空对象obj
  • 将这个空对象obj的__proto__属性指向构造函数的prototype
  • 将构造函数的作用域赋值给obj,并且执行构造函数
  • 返回这个对象obj
function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);    // 相当于 obj.__proto__ = fn.prototype
    const ret = fn.apply(obj, arg);             // 将构造函数的作用域赋值给obj,再执行构造函数
    // console.log(ret instanceof Object)          // false
    return ret instanceof Object ? ret : obj;   // return obj
}

测试:

function Dog(name) {
    this.name = name
    this.say = function(){
        console.log(`name = ${this.name}`)
    }
}

function Cat(name) {
    this.name = name
    this.say = function(){
        console.log(`name = ${this.name}`)
    }
}


var dog = _new(Dog, 'tony')
dog.say()
console.log(dog instanceof Dog)     // true
console.log(dog instanceof Cat)     // false

var cat = _new(Cat, 'tom')
cat.say()
console.log(cat instanceof Dog)     // false
console.log(cat instanceof Cat)     // true