前端面试|new运算符

221 阅读2分钟

一、如何实现一个new

1. 了解new 运算符

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

new关键字会进行如下操作:

  1. 创建一个空对象 {};
  2. 链接该对象(设置该对象的constructor)到另一个对象(原型对象上);
  3. 将步骤1新创建的对象作为this的上下文(该对象被绑定为this);
  4. 如果该函数没有返回对象,则返回this。

2. new Foo(...)执行时,会发生什么?

  1. 一个继承自Foo.prototype的新对象被创建
  2. 使用指定的参数调用构造函数Foo,并将 this 绑定到新创建的对象。
    • new Foo 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。
  3. 由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)

3.自己实现new

function myNew() {
   // 构造函数就是我们传入的第一个参数。由于arguments是类数组,我们不能直接使用shift方法,我们可以使用call来调用Array上的shift方法,获取constr
   var constr = Array.prototype.shift.call(arguments);

   // 创建新对象,并且新对象可以使用构造函数的原型
   var obj = Object.create(constr.prototype);

   // 执行构造函数中的代码,为这个新对象添加属性
   var result = constr.apply(obj, arguments);

   // 如果返回的是undefined,null以及基本类型的时候,都会返回新的对象;而只有返回对象的时候,才会返回构造函数的返回值。
   // 如果构造函数有返回值,则返回;否则则默认返回新对象
   return result instanceof Object? result : obj;
 }
 function Person(name){
     this.name = name
 }
 
 //验证:
 var P2 = myNew(Person, "小名")
 console.log(P2.name)//小名