Object.create() 和 new Object()

object.create(proto, propertiesObject)

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.
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容