js实现new

我们在使用new去创建构造函数的时候会经历四个步骤:

  • 创建一个新对象
  • 将构造函数的作用域赋值给新对象(因此this就指向了这个新对象)
  • 执行构造函数中的代码(为这个新对象添加属性)
  • 返回新对象

下面看一下代码实现:

function my_new(Super, ...args) {
    const obj = {}
    obj._proto_ = Super.prototype // 将 构造函数 的 原型对象 赋值给新建对象的 隐式原型
    const result = Super.call(obj, ...args) // 执行 构造函数 并将 构造函数里面的this指向 新建对象obj
    return typeof result === 'object' ? result : obj // 如果 执行结构是一个对象,那么就返回执行结果 否则返回新建对象
}

是不是很简单,下面做一道题来温习一下

function Fn(a) {
    this.a= a

    return {
      a: 2,
      b: 3,
    }
}
Fn.prototype.a = 1
Fn.prototype.b = 2
Fn.prototype.c = 3
const fn = new Fn(4)
console.log(fn.a, fn.b, fn.c) // 最终会输出什么呢

答案就是:2,3,undefined
解析:实际上构造函数Fn返回的是一个新的对象,根据polyfill我们看到以返回对象优先,所以a,b输出2,3是没什么疑问的,而c不在返回的对象上,所以是undefined

function Fn(a) {
    this.a= a

    return ''
}
Fn.prototype.a = 1
Fn.prototype.b = 2
Fn.prototype.c = 3
const fn = new Fn(4)
console.log(fn.a, fn.b, fn.c) // 这回又会输出什么呢

答案是:4,2,3
解析:这回构造函数Fn返回了一个字符串,根据polyfill我们可以看出,当构造函数执行结果不是一个对象的时候,就返回的新创建的对象,新对象继承了构造函数的原型对象,所以a返回4,而构造函数在外部改变了原型对象上的属性,所以b,c返回2,3

最后我们看一个比较有意思的题

function Fn(a) {
    this.a= a

    return []
}
Fn.prototype.a = 1
Fn.prototype.b = 2
Fn.prototype.c = 3
const fn = new Fn(4)
console.log(fn.a, fn.b, fn.c) // 这个输出什么

答案是:三个undefined
解析:构造函数Fn返回一个数组,这个数组上没有a,b,c,所以都是undefined

好了,如果能不看答案就理解这三个题,就能很好的理解new的过程了

参考文章:

posted @ 2020-08-31 22:18  毛小星  阅读(381)  评论(0)    收藏  举报