JS中new做了什么?如何手写new

212 阅读2分钟

MDN中对new的解释:

developer.mozilla.org./zh-CN/docs/…

new做了什么?

  1. 创建一个空的简单JavaScript对象(即{});

  2. 为步骤1新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象 ;

    至此我们要理解下面的代码obj.__proto__ = fn.prototype,这里就需要联想到原型的三角关系。

0b28432f-ce10-4d44-aefa-aac8f3b2d551.png

  1. 原型:每个函数都会自动附带一个属性prototype,这个属性的值是一个普通对象,称之为原型对象

  2. instance,通过new产生的对象称之为实例。

    (由于JS中所有对象都是通过new产生的,因此,严格来说,JS中所有对象都称之为实例)

  3. 每个实例都拥有一个特殊的属性__proto__,称之为隐式原型,它指向构造函数的原型 。

  4. 将步骤1新创建的对象作为this的上下文 ;

  5. 如果该函数没有返回对象,则返回this

有些同学可能不理解什么是上下文,请看下面。

this(上下文对象)

执行上下文:global、function 或 eval。分为全局上下文,函数上下文,类上下文。

this(上下文对象):this指向的是一个对象,这个对象我们称为函数执行的上下文对象 。

  • 我们每次调用函数时,解析器都会将this作为隐含的参数传递进函数。

  • 使用this,根据函数的调用形式不同,this的值也不同(this会指向不同的对象)。

  • this 关键字是 JS 中的动态作用域机制,是为了在 JS 中加入动态作用域而做的努力,因为this指向的对象是在函数调用时绑定的。

    在任何函数中,this的指向都不是静态的(static)。它总是在你调用一个函数,但尚未执行函数内部代码前被指定。即this的指向与函数被调用的方式(语法)有关。

  • this在不同情况下的指向

    1. 以函数的形式调用时,this是window
    2. 以方法的形式调用时,this是调用方法的对象(如果以类的静态方法调用时,即Demo.test(),这里Demo是一个类,this此时指向这个类)
    3. 以构造函数的形式调用时,this就是新创建的对象
    4. call()apply()的方法调用时,this就是指定的那个对象。

如何手写new?

function myNew(fn, ...args) {
  let obj = {};
  obj.__proto__ = fn.prototype;
  const result = fn.apply(obj, args);
  return result instanceof Object && result!=null? result : obj;
}

function Test(name) {
  this.name = name;
  this.print = function(){
      console.log('name:'+this.name)
  }
}
const test = myNew(Test, "demo");
console.log(test,test.name);
test.print()