js new操作符个人理解

161 阅读2分钟

工作了快两年了,用es6+react平时写写业务代码感觉也没啥问题。感觉前端确实入门比较容易但是深入难。有些东西可能知道这么用可以却不知道里面的具体实现或者思想。最近正好在回顾一些半知半解的概念,写一遍也给自己加深一遍记忆吧。

new是用来干嘛的?

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。 是不是感觉很绕口?简而言之,就是用来创建实例的。这里的实例有两种情况:用户定义的对象类型的实例、具有构造函数的内置对象的实例。下面分别来介绍一下。

具有构造函数的内置对象的实例

function Car(make, model, year) {
   this.make = make;
   this.model = model;
   this.year = year;
}

var mycar = new Car("Eagle", "Talon TSi", 1993); // Car {make: 'Eagle', model: 'Talon TSi', year: 1993}

用户定义的对象类型的实例

function Car(make, model, year) {
   this.make = make;
   this.model = model;
   this.year = year;
   return {}
}

var mycar = new Car("Eagle", "Talon TSi", 1993); // {}

这里返回了自定义的对象

new的内部到底做了什么?

function myNew(Con, ...args) {
  let obj = {}
  Object.setPrototypeOf(obj, Con.prototype)
  let result = Con.apply(obj, args)
  return result instanceof Object ? result : obj
}

下面具体解释一下每一步:

  1. 创建一个空的简单JavaScript对象(即let obj = {});
  2. 为步骤1新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象 ;这段代码等同于 obj.__proto__ = Con.prototype。如果不熟悉原型链的同学可以先去复习一下。
  3. 将步骤1新创建的对象作为this的上下文 ;这一步是最难想通的,首先我们要先执行Con函数也就是new操作符后跟着的构造函数(上面的Car),会发现执行完会在window对象中添加三个属性(make, model, year),但是这和我们的目标不一致啊,我们想的是在obj中添加这两个属性,所以这里用到了apply来改变Con执行的上下文环境。
  4. 如果该函数没有返回对象,则返回this。这里就为了区分最上面所说的,你要的是自定义对象还是构造函数的内置生成的对象。

结尾

一个小小的new包括了js的很多基本概念:this,原型链,对象...每一块都可以拿出来写上上万字。学海无涯苦作舟!!