手撕new操作符

302 阅读1分钟

new操作符做了什么?

  1. 在内存中创建一个对象
  2. 将新对象内部的__propto__赋值为构造函数的prototype属性(构造函数的原型对象)
  3. 将对象作为构造函数的上下文。同时执行构造函数内代码,给新对象添加属性
  4. 对构造函数的返回值进行判断处理
function Per() {
    this.name = '张三'
}
Per.prototype.age = 22

const p1 = new Per() // new 一个 Per 的实例 p1

// 1.创建一个实例对象
console.info(p1) // Per {name: '张三'}

// 2.实例对象的 __proto__ 等于 构造函数的 prototype(原型对象)
console.info(p1.__proto__ === Per.prototype) // true

// 3.实例对象做为构造函数的上下文,继承构造函数的属性
console.info(p1.name) // '张三'


function Per2() {
    this.name = '李四'
    return []
}

const p2 = new Per2()
// 4.实例的为{}, 构造函数返回值,如果是不为null的对象返回对象,否则返回构造函数对象
console.info(p2) // []

new操作符的模拟实现

function MyNew() {
    // 1.创建新对象
    const obj = new Object() // {}
    // 2.获取入参-构造函数
    const Constructor = [].shift.call(arguments)
    // 3.新对象 __proto__ 指向构造函数 prototype 属性(原型对象)
    obj.__proto__ = Constructor.prototype
    // 4.新对象获取构造函数属性与方法,并获取返回结果
    const result = Constructor.apply(obj, arguments)
    // 5.判断构造函数的返回结果是否为非null对象,是返回否则返回新对象
    return typeof result === 'object' && result !== null ? result : obj
}
function Per(name) {
    this.name = name
}
const obj = MyNew(Per, '王五')