JS中對象(若無特殊說明,本文中的對象都爲對象實例,即便是空對象實例)可謂是一個核心的概念,縱觀整個JS的數據結構如String
、Number
、Array
、Boolean
等,都有其對應的對象。細細數來,感受上就是JS裏一切數據皆對象(除了純數字、null
和undefined
外,其餘數據均可以訪問到__proto__
屬性)。本文將淺析一下JS中的對象及相關概念。瀏覽器
JS中的對象本質上就是一個若干個無序的鍵值對組成的集合。每一個鍵值對就是對象的屬性或方法。而對象中的每一個屬性都對應着有屬性描述符,屬性描述符分爲數據描述符和存儲描述符。屬性描述符又包含了如下幾個屬性。數據結構
數據描述符和存取描述符均具備如下可選鍵值:函數
configurable
當且僅當該屬性的 configurable 爲 true 時,該屬性描述符纔可以被改變,也可以被刪除。默認爲 false。
enumerable
當且僅當該屬性的 enumerable 爲 true 時,該屬性纔可以出如今對象的枚舉屬性中。默認爲 false。
數據描述符同時具備如下可選鍵值:性能value
該屬性對應的值。能夠是任何有效的 JavaScript 值(數值,對象,函數等)。默認爲 undefined。
writable
當且僅當該屬性的 writable 爲 true 時,該屬性才能被賦值運算符改變。默認爲 false。
存取描述符同時具備如下可選鍵值:prototypeget
一個給屬性提供 getter 的方法,若是沒有 getter 則爲 undefined。該方法返回值被用做屬性值。默認爲 >undefined。
set
一個給屬性提供 setter 的方法,若是沒有 setter 則爲 undefined。該方法將接受惟一參數,並將該參數的新值>分配給該屬性。默認爲 undefined。code
對象的屬性和方法中有幾個特殊的存在:對象
constructor
繼承
該屬性指向對象的構造函數ip
__proto__
(非標準,不推薦使用)原型鏈
該屬性指向對象的構造函數的原型對象,由於對象沒有prototype
屬性,因此經過該屬性指向它。此屬性爲訪問器屬性,不推薦使用。若須要獲取對象的原型對象能夠用Object.getPrototypeOf(obj)
來獲取。
經過對象訪問的屬性和方法除了來自對象自身定義的之外,還有從其原型鏈上繼承的屬性和方法。
對象的原型對象實質上是對象的構造函數的原型對象。能夠用Object.setPrototypeOf(obj,prototype)
改變對象的原型對象。
訪問對象的原型對象有兩種方法,一是經過內置屬性 __proto__
訪問,二是經過Object方法Object.getPrototypeOf(obj)
訪問。兩種方法都有其侷限性,第一種方法不是ES標準所支持的,雖然ES6已經支持了。由於__proto__
屬性時訪問器屬性,因此能夠修改對象的原型對象(這樣很影響性能)。第二種方法在IE瀏覽器中的支持狀況是IE9+。整體上講,推薦第二種方法去訪問對象的原型對象。若是想要替換原型對象,則可用 Object.setPrototypeOf(obj,prototype)
從新設置其原型對象。
全部的對象都是經過構造函數實例化出來的。Object
也不例外。
對象的構造函數恆等於實例出該對象的構造函數的原型對象的constructor
屬性指向的函數。即
var obj = new A(); obj.constructor===A.prototype.constructor
一個對象,若是沿着原型鏈找下去,最終都會找到Object構造函數、原型對象相互之間糾纏不休,你中有我,我中有你。