JavaScript對象的原型(prototype)、類(class)和可擴展性(extendible)

每一個JavaScript對象都有與之相關的原型(prototype)、類(class)和可擴展性(extendible)。函數

原型屬性

對象的原型屬性是用來繼承屬性的。咱們常常把一個對象的原型屬性稱作「原型」。在JavaScript中有三種方式建立對象。prototype

  • 對象直接量
var o = { x: 1 };

經過對象直接量建立的對象都有同一個原型對象,即Object.prototype。code

  • 經過new建立對象
var o1 = new Object();
var a = new Array();

經過new關鍵字和構造函數調用建立的對象的原型就是構造函數的prototype屬性的值。好比上面的經過new Object()建立的對象也繼承自Object.prototype。經過new Array()建立的對象的原型就是Array.prototype。全部的內置構造函數(以及大部分自定義的構造函數)都具備一個繼承自Object.prototype的原型。因此,Array.prototype的屬性繼承自Object.prototype,由new Array()建立的Array對象的屬性同時繼承自Array.prototype和Object.prototype。這一系列連接的原型對象就是所謂的「原型鏈」(prototype chain)。對象

  • Object.create()

ECMAScript 5 定義了一個名爲Object.create()的方法,它建立一個新對象,其中第一個參數是這個對象的原型。第二個參數是可選參數,用以對對象的屬性進行進一步描述。Object.create()是一個靜態函數,而不是提供給某個對象調用的方法。繼承

// 一個參數
var o2 =  Object.create({x:1});
// 兩個參數
var o3 = Object.create({x:1}, {
  // foo會成爲所建立對象的數據屬性
  foo: { 
    writable:true,
    configurable:true,
    value: "hello" 
  },
  // bar會成爲所建立對象的訪問器屬性
  bar: {
    configurable: false,
    get: function() { return 10 },
    set: function(value) {
      console.log("Setting `o.bar` to", value);
    }
  }
});

o3的原型是對象{x:1},而{x:1}的原型是Object.prototype,因此o3同時繼承自{x:1}和Object.prototype。ip

縱觀上面三種方法,幾乎全部JavaScript都有原型對象,而且都直接或者間接繼承自Object.prototype。沒有原型的對象並很少,Object.prototype就是其中之一,它不繼承任何屬性。
下面介紹兩個與原型相關的方法:原型鏈

  • Object.getPrototypeOf(),在ECMAScript中,將對象做爲參數傳入Object.getPrototypeOf()能夠查詢它的原型。
  • isPrototypeOf(),而要檢測一個對象是不是另外一個對象的原型,可使用方法isPrototypeOf()方法。

類屬性

對象的類屬性是一個字符串,用以表示對象的類型信息。ECMAScript 3 和ECMAScript 5 都沒有設置這個屬性的方法,有一種間接的方法能夠查詢它——默認的toString方法(基礎自Object.prototype)返回了以下格式的字符串:
[object class]
所以想要得到對象的類,能夠調用對象的toString()方法,而後提取已返回字符串的第8個到倒數第二個位置之間的字符串。須要注意的是,不少對象繼承的toString()方法重寫了,爲了能調用正確的toString()版本,必須間接的調用Function.call()方法。下面的classOf()函數能夠返回傳遞給它的任意對象的類:字符串

function classOf (o) {
    if (o === null) return 'Null';
    if (o === undefined) return 'Undefined';
    return Object.prototype.toString.call(o).slice(8, -1);
}

可擴展性

對象的擴展性用以表示是否能夠給對象添加新屬性。全部內置對象和自定義對象都是顯式可擴展的,宿主對象的可擴展性是由JavaScript引擎決定的。get

  • Object.esExtensible(),判斷對象是不是可擴展的
  • Object.preventExtendsions(),將對象轉換爲不可擴展的,一旦將對象轉換成不可擴展的,就沒法再將其轉換爲可擴展的了
  • Object.seal(),將對象轉換成不可擴展的和不可配置的
  • Object.freeze(),鎖定對象——「凍結」,將對象轉換成不可擴展的和不可配置的,全部的數據屬性都設置爲只讀的。
  • Object.isFrozen(),檢測對象是否被「凍結」
相關文章
相關標籤/搜索