Object.create() 和 new Object()

Object.create() 和 new Object()

object.create() 是使用指定的原型proto对象及其属性propertiesObject去创建一个新的对象。(mdn)

  • proto 是必填参数,就是新创建出来的对象的原型 (新对象的 __proto__属性指向的对象),值得注意的是当protonull的时候创建的新对象完全是一个空对象,没有原型(图一),也就是没有继承Object.prototype上的方法。(如hasOwnProperty() toString() 等)
    图1
  • propertiesObject是可选参数,作用就是给新对象添加新属性以及描述器(图2),具体可参考 Object.defineProperties() - mdn 的第二个参数。需要注意的是新添加的属性是新对象自身具有的属性也就是通过hasOwnProperty() 方法可以获取到的属性,而不是添加在原型对象里。(图3)
图2

图3
具体三个步骤就是:
  1. 创建一个对象
  2. 继承指定父对象
  3. 为新对象扩展新属性

自己实现一个Object.create()

Object.myCreate = function (obj, properties)  {
  var F = function ()  {}
  F.prototype = obj
  if (properties) {
     Object.defineProperties(F, properties)
  }
  return new F()
}

Object.myCreate({}, {a: {value: 1}}) // {a: 1}

new Object()

  • new 运算符是创建一个自定义对象或者具有构造函数的内置对象的实例mdn
  • 使用new运算符会创建一个新的对象,它继承自构造函数的prototype,也就是说它的__proto__属性会指向构造函数的prototype
  • new Object() 也就是具有构造函数的内置Object的实例,新创建的对象的__proto__属性会指向Object的prototype

扩展:实例复现new的构造过程:

var objectFactory = function ()  {
   var obj = new Object()              // 从Object.prototype上克隆一个空对象 此时 __proto__ 指向Object.prototype
   var Constructor = [].shift.call(arguments)  //取得构造器
   obj.__proto__ = Constructor.prototype  // 指向构造器的prototype
   var ret = Constructor.apply(obj, arguments)  
   return typeof ret === 'object' ? ret : obj
}

function Person (name) {
this.name = name
}

Person.prototype.getName = function () {
return this.name
}

var a = objectFactory(Person, ‘nancy’)
console.log(a.name) // nancy
console.log(a.getName) //nancy
console.log(Object.getPrototypeOf(a) === Person.protoType) //true

总结区别

  • Object.cerate() 必须接收一个对象参数,创建的新对象的原型指向接收的参数对象,new Object() 创建的新对象的原型指向的是 Object.prototype. (表述有点啰嗦,简洁点说就是前者继承指定对象, 后者继承内置对象Object)
  • 可以通过Object.create(null) 创建一个干净的对象,也就是没有原型,而 new Object() 创建的对象是 Object的实例,原型永远指向Object.prototype.

猜你喜欢

转载自blog.csdn.net/osdfhv/article/details/86477845