假設我們有個 Bar 類並創建了一個 bar 實例
function Bar() {
this[2] = 2
this[3] = 1
this['b'] = 'b'
this[1] = 1
this['a'] = 'a'
}
const bar = new Bar()
// 打印屬性
for (key in bar) {
console.log(`index:${key} value:${bar[key]}`)
}
// 打印的屬性順序
// index:1 value:1
// index:2 value:2
// index:3 value:3
// index:b value:b
// index:a value:a
可以發現屬性的打印順序和我們賦值順序是不一樣的,這是因為屬性和屬性間也是有區別的。
bar 擁有兩個隱藏屬性 elements 和 properties。
數字屬性 2、3、1 會放到 elements 屬性中,被稱為排序屬性。elements 屬性指向一個 elements 對象,在 elements 對象中,會按照屬性數字的大小(從小到大)存放排序屬性 —— 以 2、3、1 的順序輸入的屬性會以 1、2、3 的順序輸出。
字符串屬性 b、a 稱為常規屬性,會放到 properties 屬性中。properties 屬性指向一個 properties 對象,在 properties 對象中,會按照屬性創建的先后順序保存了常規屬性 —— 以 b、a 的順序輸入的屬性會以 b、a 的順序輸出。
elements 對象和 properties 對象都是用線性結構存儲屬性的,但這樣存在效率問題,因為在查某個屬性的時候,要先去查 elements 對象或 properties 對象,增加了查找步驟。為了減輕這個問題,引擎會將部分常規屬性(默認是 10 個)直接存到對象下面,稱為對象內屬性。
將保存在線性結構里的屬性稱為快屬性,快屬性查找快,增刪慢;當對象屬性很多的時候,就會放大線性結構增刪屬性的缺點,因此引擎會利用非線性結構(字典)來保存屬性,這時候被存儲的屬性稱為慢屬性。
