new时做了什么

对于构造器函数或者函数,可以使用new操作符执行。new时大致做了如下的事:

  1. 创建一个空白对象obj。
  2. 将obj的原型设置成构造器函数的prototype属性。
  3. 将构造器函数的this绑定为obj。
  4. 执行构造器函数。如果构造器函数显式返回一个对象obj2,则返回obj2。否则返回obj。

第4点意味着你可以改写实例化时返回的对象。暂时还没有想到可能的应用场景。


function Fish(name,age){
    this.name=name;
    this.age=age;
}

var fish=new Fish('胖头鱼',18);

console.log(fish)//Fish { name: '胖头鱼', age: 18 }


function Fish(name,age){
    this.name=name;
    this.age=age;

    return '猫';//只有显示返回对象才能改写实例化时返回的对象。
}

var fish=new Fish('胖头鱼',18);

console.log(fish)//Fish { name: '胖头鱼', age: 18 }


function Fish(name,age){
    this.name=name;
    this.age=age;

    return {
        name:'猫',
        age:1
    }
}

var fish=new Fish('胖头鱼',18);

console.log(fish)//{ name: '猫', age: 1 }    

如果写一个函数模拟new的过程,大致如下:


function Fish(name, age) {
  this.name = name;
  this.age = age;
}

function callNew(Constructor, ...params) {
  const obj = Object.create(Constructor.prototype);
  const returned = Constructor.apply(obj, params);
  if (Object.prototype.toString.call(returned) === '[object Object]') {
    return returned;
  } else {
    return obj;
  }
}

var fish=callNew(Fish,'胖头鱼',18);

console.log(fish); //Fish { name: '胖头鱼', age: 18 }