欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中普通屬性和排序?qū)傩栽斀?/h1>
 更新時(shí)間:2023年09月18日 10:14:48   作者:LBruse  
JavaScript屬性是對(duì)象中的特性,用于描述對(duì)象的狀態(tài),每個(gè)JavaScript對(duì)象都有一組屬性,可以通過(guò)點(diǎn)號(hào)(.)或方括號(hào)([])訪問(wèn)和操作這些屬性,本文將給大家講講JavaScript中你所不知道的普通屬性和排序?qū)傩?需要的朋友可以參考下

普通屬性

JavaScript中定義對(duì)象時(shí),普通的以字符串為鍵定義的屬性為普通屬性,特點(diǎn)是在遍歷對(duì)象屬性時(shí)根據(jù)創(chuàng)建時(shí)的順序排序

const obj = {
    'name': 'Bruse',
    'age': 16,
}
for (const key in obj) {
    console.log(key)
}

輸出順序?yàn)?/p>

name
age

排序?qū)傩?/h2>

排序?qū)傩詣t是以數(shù)字為鍵定義的屬性,特點(diǎn)是按照索引值的大小進(jìn)行升序排序,優(yōu)先級(jí)優(yōu)于普通屬性。

const obj = {
    'name': 'Bruse', // 普通屬性
    'age': 16, // 普通屬性
    2: 'obj2' // 排序?qū)傩?
}
obj[1] = 'obj1' // 排序?qū)傩?
obj[99] = 'obj99' // 排序?qū)傩?
obj[10] = 'obj10' // 排序?qū)傩?
for (const key in obj) {
    console.log(key)
}

輸出

1
2
10
99
name
age

可以看到在使用for ... in 遍歷obj的屬性時(shí),排序?qū)傩?/code>遍歷順序優(yōu)先于普通屬性,同時(shí)排序?qū)傩?/code>也是按照鍵值進(jìn)行升序排序的,鍵值越小,遍歷順序越往前

字符串?dāng)?shù)字作為鍵

obj中新建一個(gè)鍵為'3',值為112的屬性,遍歷obj屬性名并輸出

const obj = {
    'name': 'Bruse', // 普通屬性
    'age': 16, // 普通屬性
    2: 'obj2', // 排序?qū)傩?
    '3': 112 // 轉(zhuǎn)換,也是排序?qū)傩?
}
obj[1] = 'obj1' // 排序?qū)傩?
obj[99] = 'obj99' // 排序?qū)傩?
obj[10] = 'obj10' // 排序?qū)傩?
for (const key in obj) {
    console.log(key)
}

輸出

1
2
3
10
99
name
age

可以看到即便在定義屬性鍵時(shí),是字符串類型的數(shù)字3,也會(huì)做一下轉(zhuǎn)換,將其轉(zhuǎn)換為排序?qū)傩?/p>

排序?qū)傩?VS 普通屬性

存儲(chǔ)方式

首先排序?qū)傩?/code>和普通屬性在對(duì)象中的存儲(chǔ)方式不一樣

可以簡(jiǎn)單地理解為obj對(duì)象中,分別有著elementsproperties兩個(gè)內(nèi)置的屬性,elements可以理解為是一個(gè)數(shù)組,而數(shù)字鍵則是屬性在該數(shù)組中的下標(biāo),也就是內(nèi)存偏移量。通過(guò)下標(biāo)訪問(wèn)數(shù)組中的某個(gè)元素是很快的。當(dāng)我們要訪問(wèn)obj.1時(shí),會(huì)先從obj對(duì)象中內(nèi)置的elements屬性中通過(guò)1這個(gè)下標(biāo)進(jìn)行查詢,最終找到obj[1]的值為obj1。

properties可以理解為是一個(gè)Map,而字符串鍵則是該Map中的keyvalue則是對(duì)應(yīng)的屬性值。當(dāng)訪問(wèn)obj.name時(shí),會(huì)先從elements中進(jìn)行查找,結(jié)果是找不到,然后再?gòu)?code>properties中進(jìn)行查找,但從properties中查找則沒(méi)有elements中查找快,因?yàn)?code>elements可以通過(guò)計(jì)算偏移量來(lái)進(jìn)行訪問(wèn),但是properties要hash計(jì)算訪問(wèn)。

對(duì)象內(nèi)屬性

其實(shí)上圖還并不是全貌,因?yàn)榧幢阌兄?code>elements和properties分別存放排序?qū)傩院推胀▽傩裕菬o(wú)論訪問(wèn)排序?qū)傩院推胀▽傩?code>[排序?qū)傩栽L問(wèn)速度優(yōu)于普通屬性],都是要先訪問(wèn)obj這個(gè)對(duì)象的elementsproperties內(nèi)置屬性,然后再通過(guò)屬性鍵訪問(wèn)到具體的屬性值,其實(shí)就相當(dāng)于obj.name = obj.properties.name,還存在優(yōu)化空間,這個(gè)時(shí)候對(duì)象內(nèi)屬性就出場(chǎng)了。

對(duì)象內(nèi)屬性其實(shí)就是被保存到對(duì)象自身的常規(guī)屬性,也就是真正意義上的讓obj.name不再等于obj.properties.name,而是真正的所見(jiàn)即所得obj.name

代碼測(cè)試

為了方便理解,把之前的代碼稍作修改

class People {
   constructor() {
       this.name = 'Bruse'
       this.age = 16
       this[2] = 'obj2'
   }
}
const obj = new People()
obj[1] = 'obj1' // 排序?qū)傩?
obj[99] = 'obj99' // 排序?qū)傩?
obj[10] = 'obj10' // 排序?qū)傩?
debugger  // 避免執(zhí)行過(guò)快,導(dǎo)致還來(lái)不及生成內(nèi)存快照,obj對(duì)象就已被回收
for (const key in obj) {
   console.log(key)
}

F12打開(kāi)瀏覽器開(kāi)發(fā)者工具,當(dāng)debugger阻塞住代碼往下執(zhí)行時(shí),點(diǎn)擊Memory,生成內(nèi)存快照

可以看到obj這個(gè)對(duì)象中存在內(nèi)置屬性elements和一些內(nèi)屬性name[10]、[99]、[1][2],暫時(shí)并沒(méi)有內(nèi)置屬性properties

首先因?yàn)?code>obj屬性并不多,此時(shí)對(duì)象內(nèi)屬性的數(shù)量還比較少,所以此時(shí)并不需要內(nèi)置屬性properties來(lái)存放普通屬性,而是將name等普通屬性當(dāng)做是對(duì)象的內(nèi)置屬性存放即可,訪問(wèn)速度比訪問(wèn)elementsproperties更快。

Tips:不要看到elements中10、99排在1、2前面,就以為elements不是按照數(shù)字升序排列的,因?yàn)檩敵鲋竽銜?huì)發(fā)現(xiàn)其實(shí)還是1、2、10、99這樣的順序,至于為什么在調(diào)試工具里看起來(lái)順序有點(diǎn)不太一致,我也不知道...

添加更多的排序?qū)傩?/h3>

接下來(lái)給obj塞入更多的排序?qū)傩?/p>

class People {
    constructor() {
        this.name = 'Bruse'
        this.age = 16
    }
}
const obj = new People()
for (let i = 0; i < 20; i++) {
    obj[i] = `obj${i}`
}
debugger
for (const key in obj) {
    console.log(key)
}

再看看看obj的變化,首先elements屬性中的元素變多了

同時(shí)也并沒(méi)有出現(xiàn)內(nèi)置屬性properties

因?yàn)橹皇窃黾恿烁嗟?code>排序?qū)傩?/code>,并沒(méi)有突破內(nèi)置屬性(內(nèi)置常規(guī)屬性)的數(shù)量限制

添加更多的普通屬性

接下來(lái)再塞入更多的普通屬性

class People {
    constructor() {
        this.name = 'Bruse'
        this.age = 16
        for (let i = 0; i < 20; i++) {
            this[`obj${i}`] = i
        }
    }
}
const obj = new People()
debugger
for (const key in obj) {
    console.log(key)
}

可以看到在這個(gè)時(shí)候obj的內(nèi)置屬性properties終于出現(xiàn)了

只不過(guò)貌似并不像elements那樣方便預(yù)覽其中的屬性...后來(lái)經(jīng)過(guò)一番查找和嘗試,終于是找到了解決辦法... 也很簡(jiǎn)單,就是生成內(nèi)存快照時(shí)多做一步操作,勾上“在快照中添加數(shù)字值”

再次內(nèi)存分析,好吧...因?yàn)樯?0個(gè)常規(guī)變量的緣故,貌似也還沒(méi)達(dá)到內(nèi)置屬性的限制...

將數(shù)量調(diào)整到50個(gè),可以看到elementsproperties都有了相應(yīng)存放的變量

for (let i = 0; i < 50; i++) {
    this[i] = `obj${i}`
    this[`obj${i}`] = i
}

困惑

單純?cè)贑hrome上進(jìn)行內(nèi)存分析的話,貌似即便超出了內(nèi)屬性數(shù)量限制,那多出來(lái)的一部分普通屬性,也非常直白地展示在properties之外,這個(gè)暫時(shí)不太清楚...

總結(jié)

把上述排序?qū)傩訿`普通屬性``內(nèi)屬性結(jié)合到一塊來(lái)看,那么JavaScript中的對(duì)象屬性存放結(jié)構(gòu)應(yīng)該如下圖所示

首先是為了提高訪問(wèn)速度,對(duì)象obj本身就會(huì)有一定空間存放內(nèi)屬性,在訪問(wèn)內(nèi)屬性時(shí),可以直接跳過(guò)訪問(wèn)elementsproperties這一步,直接訪問(wèn)到該屬性的值。

但是內(nèi)屬性是有一定數(shù)量限制的,所以當(dāng)超出了限制后,剩下的普通屬性會(huì)被存放到properties中,而properties有點(diǎn)像Map,在進(jìn)行屬性訪問(wèn)的時(shí)候,需要計(jì)算出鍵的hash值,然后才能訪問(wèn)到具體的屬性值。

elements則是存放排序?qū)傩?/code>用的,有點(diǎn)像Array,數(shù)字鍵即數(shù)組中的下標(biāo),所有元素按數(shù)字升序進(jìn)行排序,訪問(wèn)屬性值時(shí)則是通過(guò)下標(biāo)進(jìn)行訪問(wèn),訪問(wèn)速度會(huì)比properties要快一些。

propertieselements兩種存儲(chǔ)方式之間的VS,本質(zhì)上就像是數(shù)據(jù)結(jié)構(gòu)中的MapArray之間的VS。

以上就是JavaScript中普通屬性和排序?qū)傩栽斀獾脑敿?xì)內(nèi)容,更多關(guān)于JavaScript屬性的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論