對象的三個屬性

對象的三個屬性

每個對象都擁有三個特性(屬性)(object attribute):

  • 對象的原型(prototype)。指向另外一個對象,本對象的屬性繼承自它的原型對象。
  • 對象的類(class)。是一個表示對象類型的字符串。
  • 對象的擴展標記(extensible flag)。指明瞭(在ES5中)是否可以向該對象添加新屬性。

原型屬性

【01】對象的原型屬性是用來繼承屬性的。

【02】我們經常把“對象的原型屬性”直接叫做“對象的原型”。

【03】原型屬性是在對象創建之初就設置好的。

  • 通過對象直接量創建的對象使用Object.prototype作爲它們的原型。
  • 通過new創建的對象使用構造函數的prototype屬性作爲它們的原型。
  • 通過Object.create()創建的對象使用第一個參數(也可以是null)作爲它們的原型。

【04】在ES5中,Object.getPrototypeOf(obj)可以查詢它的原型。

並不能直接通過對象實例.prototype屬性的形式訪問到對象的原型。

不能在對象實例的prototype上添加屬性和方法。

比如:

img

img

類屬性

【01】ES3和ES5都未提供設置這個屬性的方法,並只有一種間接的方法可以查詢它。

【02】要想獲得對象的類,可以調用對象的toString()方法,然後提取已返回字符串的第8個到倒數第二個位置之間的字符。

默認的toString()方法(繼承自Object.prototype)返回瞭如下這種格式的字符串:

[object class]

很多對象繼承的toString()方法重寫了,爲了能調用正確的toString()版本,必須間接地調用Function.call()方法。

【03】

  • 通過內置構造函數(比如Array和Date)創建的對象包含“類屬性”(class attribute),它與構造函數名稱相匹配。(疑惑)
  • 宿主對象也包含有意義的“類屬性”,但這和具體的JS實現有關。
  • 對象的4種創建方式創建的對象的類屬性都是“Object”。

【04】classof()函數,可以返回任何類型任意對象的類:

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

數字、字符串和布爾值可以直接調用toString()方法,就和對象調用toString()方法一樣

這些類型的變量調用toString()方法,而不是通過它們的直接量調用toString(),比如1.toString()是不對的,而是要先聲明變量var a=1;然後調用a.toString()。

classof(null)           // => "Null"
classof(1)              // => "Number"
classof("")             // => "String"
classof(false)          // => "Boolean"
classof({})             // => "Object"
classof([])             // => "Array"
classof(/./)            // => "Regexp"
classof(new Date())     // => "Date"
classof(window)         // => "Window"(這是客戶端宿主對象)
function f() {};        // 定義一個自定義構造函數
classof(new f());       // => "Object"

可擴展性

【01】對象的可擴展性表示是否可以給對象添加新屬性。

可擴展屬性的目的是將對象“鎖定”,以避免外界的干擾。

【02】所有內置對象和自定義對象都是顯式可擴展的,除非將它們轉換爲不可擴展的,宿主對象(BOM,DOM)的可擴展性是由JS引擎定義的。

【03】如果給一個不可擴展的對象的原型添加屬性,這個不可擴展的對象同樣會繼承這些新屬性。

(zyx456:原型添加屬性,繼承原型的對象也自動獲取這些新屬性,即使該對象爲不可擴展性)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章