前端面试手写题之new的实现

470 阅读2分钟

现如今的前端面试中,常常会考察候选人的编码能力。不仅会考察基本的数据结构与算法,还会考察javascript基本功,看候选人对js基础的理解和掌握程度。

面试官:请你简单实现一下js的new

要想实现一个东西,必须要懂这个东西是做什么用的,new的基本功能是创建一个实例对象

js中实现类与对象创建的原理是构造函数和原型,ES6虽然引入了class,但其内部机制仍然没有变。

假如有一个比较简单的构造函数Animal

function Animal (name) {
  this.name = name
}

如果我们要创建一个实例对象的话,通常使用new方法构造。实例对象会继承构造函数原型上的属性与方法

const cat = new Animal('cat')
// cat.name 是 cat

懂了new是什么了之后,我们就可以用代码实现他啦~

第一步:我们把new方法挂载到Function构造函数的原型上来进行模拟

Function.prototype.myNew = function () {
  
}

第二步:new会返回一个实例对象

Function.prototype.myNew = function () {
  let obj = {}
  return obj
}

第三步:通过new创建的实例对象会继承构造函数的所有属性和方法,我们可以用Object.create方法去复制构造函数的原型,注意:这里的this指向是构造函数本身,复制之后我们就可以return了。

Function.prototype.myNew = function () {
  let obj = Object.create(this.prototype)
  return obj
}

第四步:new的过程,构造函数里的语句是会被执行的,如this.name = name,会将name赋值给实例对象,所以我们需要执行原有构造函数,并指定this指向为创建的实例对象。

Function.prototype.myNew = function () {
  let obj = Object.create(this.prototype)
  this.call(obj, ...arguments)
  return obj
}

第五步:还需要考虑一些特殊情况,需要区分构造函数执行结果是否为一个引用对象。

举一个简单的例子

function Animal (name) {
  this.name = name
  return {}
  
  const cat = new Animal('cat')
  // cat则为 {}
}
function Animal (name) {
  this.name = name
  // 当构造函数返回的是一个原始值
  return 'abc' 
  
  const cat = new Animal('cat')
  // cat则为 {name: 'cat'}
}

#### 这里我们通过instance of 来判断函数执行结果是否为一个引用对象,如果是的话则返回该结果,如果不是的话则返回我们创建的obj。

只需注意这两种特殊情况即可,那么我们最终的代码为:
Function.prototype.myNew = function () {
  let obj = Object.create(this.prototype)
  let result = this.call(obj, ...arguments)
  return result instance of Object ? result : obj
}
仅需5行代码就完成coding了~~~~~~~~: