JS -- (9) new 关键字的模拟实现

114 阅读2分钟

new new 运算符创建一个用户定义的对象类型或具有构造函数的内置对象类型的实例。

1) 那 new 具体实现了哪些功能呢?
  • 创建一个新对象实例,并且该对象:

      - 可以访问到 构造函数 里面的属性和方法
      - 可以访问到 构造函数 的实例对象上的属性和方法
    

补:构造函数

构造函数与普通函数唯一的不同就是调用方式的不同,使用 new 操作符调用的就是构造函数。当然,构造函数也可以进行普通调用,此时其内部的属性会被添加到全局 windows对象身上,即此时(构造)函数内部的this执行 windows!!

栗子:

function Otaku (name, age) {
    this.name = name;
    this.age = age;
    this.habit = 'Games';
}

Otaku.prototype.sayYourName = function () {
    console.log('I am ' + this.name);
}

var person = new Otaku('Kevin', '18');
console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // 60
person.sayYourName(); // I am Kevin

2) new操作符的执行过程 && 模拟实现:

new操作符的执行过程:

  • 创建一个新对象 newObj
  • 设置该实例对象的原型 _ _ proto _ _ 指向该构造函数的原型对象(prototype属性)
  • 让该构造函数内部的this指向该创建的新对象
  • 执行该构造函数,初始化实例对象
  • 判断该构造函数的返回类型,如果不返回或者返回的是原始值类型,就返回该新创建的对象;如果返回的是引用类型,就照着返回!!

模拟实现:

因为 new 操作符不是一个函数,不好直接模拟,所以我们写一个函数,命名为 objectFactory(构造函数,参数),来模拟 new 的效果。

function objectFactory(){
     var newObj = new Object();
     // 从传入的参数中,截取获得第一个,得到构造函数
     var Constructor = [].shift.call(arguments);
     // 设置新创建的对象实例的原型属性
     newObj.__proto__ = Constructor.prototype;
     // 执行构造函数(绑定构造函数内部的this指向新创建的对象)
     var result = Constructor.call(newObj,...arguments)
     // 判断构造函数的返回类型
     return typeof ret === 'object' ? ret : obj;
}