你的浏览器不支持canvas

Enjoy life!

discrimination - Object.create()和new一个新对象的区别

Date: Author: JM

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。

区别

const Base = function () {}
const b1 = new Base()
const b2 = Object.create(Base)
console.log(b1)
console.log(b2)
  • 输出结果如下:

image

  • 从上述图片可以看出:b1.__proto__ 是一个对象 Base {}b2__proto__ 是一个函数 f ()
  • 这里提出一个疑问:为什么 b2.__proto__ 不是 Base{}

  • Object.create(prototype, descriptors),用原生js实现的代码如下:
Object.create = function (obj) {
    const F = function () {}
    F.prototype = obj
    return new F()
}
  • 上述代码做了以下这些事情:
    • 新建一个空函数(什么都不干)
    • 将对象obj赋值给空函数F的原型对象prototype
    • 最终返回一个新对象

  • 接下来,说一说 const b1 = new Base()都干了些什么!
    • 首先,创建了一个Object对象b1
    • 接着,让 b1__proto__ 指向了 Base.prototype 对象
    • 最后,调用 call 强行转换作用环境
const b1 = new Object()
b1.[[Prototype]] = Base.prototype
// 或 b1.__proto__ = Base.prototype
Base.call(b1)

  • 接着再看下面的代码
  • demo
 const Base = function () {
  this.a = 1
}

Base.prototype.b = 2

const b1 = new Base()
const b2 = Object.create(Base)

console.log(b1) // Base {a: 1}
console.log(b2) // Function {}

console.log(`b1.a = ${b1.a}, b1.b = ${b1.b}`) // b1.a = 1, b1.b = 2
console.log(`b2.a = ${b2.a}, b2.b = ${b2.b}`) // b2.a = undefined, b2.b = undefined

console.log(b2.__proto__ === Base) // true
console.dir(b2.prototype === Base.prototype) // true
  • 输出结果如下:

image

  • 从图中你会发现,属性 a 只存在于b1中,而属性b存在于b1__proto__对象中以及其constructorprototype对象中,但是, 对于b2来说,b2只存在于constructorprototype对象中。
  • 请看下图:

image

image


  • 先回答这个问题:为什么 b2.__proto__ 不是 Base{}
    • 可从图中看到,Object.create 最终返回的是 new F (),根据 discrimination - proto 和 prototype 的区别里面所讲到的规则, b2.__proto__ 的指向规则是基于创建其的构造函数,因此,其值肯定是 f ()Base {}

  • 为什么 b2 不能获取到 b 的值?
  • 先看:b2.__proto__ === Basetrue 的原因是:
    • 因为 b2.__proto__ = F.prototype
    • 又因为 F.prototype = Base
    • 所以 b2.__proto__ = Base
  • 从图中可知道,通过 Object.create 构造的 b2 没有指向 Baseprototype,而是直接执行Base 【即:b2.__proto__ = Base 而不是 b2.__proto__ = Base.prototype】, 所以在Base.prototype上定义的b,只单纯是Base.prototype上的一个属性。

传递给Object.create()的参数是对象

 const person = {
    name: 'jm',
    age: 12
  }
  const obj = Object.create(person)
  console.log(obj)
  • 结果如下图:

image

总结

  • new 关键字必须是以 function 定义的。
  • Object.create()functionobject 都可以进行构建。

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。