songning0605 / blog

整理记录
1 stars 0 forks source link

new操作符的工作原理 #18

Open songning0605 opened 4 years ago

songning0605 commented 4 years ago

参考:

在学习 new 原理钱,建议先熟悉 call, apply 的原理

对于 new 操作符,JavaScript高级程序设计(第三版)中是这样解释的

要创建Person的新实例,必须使用new操作符。以这种方式调用构造函数实际上会经历以下4个步骤:

1)创建一个新对象;

let instance = new Object();

2)设置原型链

instance.__proto__ = Person.prototype;

3)确定this指向,执行构造函数中的代码(为这个新对象添加属性);

function newObject() {
  var instance= new Object();

  Constructor = [].shift.call(arguments);  // 取得外部传入的构造器

  instance.__proto__ = Constructor.prototype; // 设置原型链

  var res = Constructor.apply(instance, arguments) // 执行构造函数,给instance添加属性

  return typeof res === 'object' ? res : instance;  // 确保构造器总是返回一个对象,这一个过程就是第四步讲到的内容
}

4)返回新对象。(具体过程如下)
判断构造函数的返回值类型: 如果是值类型,就丢弃它,还是返回instance。 如果是引用类型,就返回这个引用类型的对象,替换掉instance。

songning0605 commented 4 years ago

面试回答

  1. 作用:new运算符会创建一个目标构造函数的实例
  2. 原理:(new运算符会进行如下操作)
    • 创建一个简单的对象
    • 设置这个简单对象的原型为构造函数的原型
    • 执行构造函数,设置构造函数的this指向为新创建简单对象,执行构造函数中定义的行为
    • 如果构造函数没有返回值或者返回值是简单类型,则new的最终结果是新创建的对象,如果构造函数的返回结果是一个对象,那么new的最终结果是构造函数的返回结果。
    • 这就是new的执行原理
songning0605 commented 4 years ago
/**
 * 1、创建一个新的对象
 * 2、设置对象的原型属性
 * 3、确定 this 指向
 * 4、返回创建的对象
 */

function create() {
    // 1、创建一个新的对象
    var obj = new Object();

    /**
     * 2、设置对象的原型属性,要分为两小步
     *  1)拿到构造函数
     *  2)设置创建的对象原型属性为构造函数的原型对象,实现继承的目的
     */
    // 1)拿到构造函数
    var Con = [].shift.call(arguments);
    // 2)设置对象的原型属性
    obj.__proto__ = Con.prototype;

    /**
     * 3、确定 this 指向
     * 这里其实就是使用 apply 借用构造函数,并指定构造函数中的 this 为新创建的对象,达到继承的目的
     */
    var result = Con.apply(obj, arguments);

    /**
     * 4、返回创建对象,但是这里又分为两种情况
     *  1)如果构造函数返回值是引用类型,则返回构造函数的返回值。
     *  2)如果构造函数的返回值是基本类型,则返回新创建的对象。
     */
    return result instanceof Object ? result : obj;
}