JavaScript巧用對象的引用解決三級聯動
在開發過程中,我們經常會有操作需要進行三級聯動操作,比較典型的如:省市區的選擇,菜單欄的選擇等。當我們遇到這個問題的時候,為了便於開發,我們都是通常使用第三方的插件來實現數據的聯動效果。這時候按照聯動數據,後端往往會給我們一段數據數據格式如圖所示:
但當數據到了前端以後,為了方便,前端往往又需要將數據再次遍歷一遍,以便將參數的屬性名,或者添加額外字段,而後臺為了生成這麽一種數據格式,也是已經經過一次遍歷的。
因此,從方案上來說,最好是一遍解決問題的。而這個遍歷由前端完成更為合適一點。
這時候後端給我們的數據格式是這樣的。(另外接口)
此時我們需要做的就是根據code 拼接成合適的含有父子關系的數組。根據後端定義,code 長度為 3 時,是第一級,為 6 時為第二級,以此類推。001 的子元素為 001001, 001 的兄弟元素為 002。
遍歷的代碼比較簡單,只是在我沒有想到在這個地方,根據 對象變量存儲的數據是真實對象所在地址字節時 這個概念來進行遍歷的時候。對於如何編寫這一函數,我無法進行。
const arr = [ { "code": "001" }, { "code": "001001" }, { "code": "002" }, {"code": "002001" }, { "code": "002002" }, { "code": "002003" }, { "code": "002004" }, { "code": "002005" } ] //因為是值的引用,所以根據這一存儲的原理,每次遍歷以後都可以將之前的數據補充完整,所以遍歷以便以後,// obj[001]就是code 為001 且包括其所有子元素的一個對象, // obj[001001]就是code 為001001 且包括其所有子元素的一個對象(不包括父元素) // 而我們obj[001]也早已經將數據保存到了resultArr中。這時候resultArr就是最終結果。 // (數組也是存儲的每個元素的真實所在位置的地址的一個數組) let obj = new Map() //以 key :value 的形式,根據code存放每個value let resultArr = [] arr.map((currentValue, index, array) => { let code = currentValue.code obj[code] = currentValue // 當code長度為3時,代表為一級目錄 if (currentValue.code.length === 3) { resultArr.push(obj[code]) } else { let auth = currentValue.auth let parentid = currentValue.code.substring(0, currentValue.code.length - 3) // 獲取當前currentValue的父元素的pid if (obj[parentid].list) { obj[parentid].list.push(currentValue) } else { obj[parentid].list = [] obj[parentid].list.push(currentValue) } } }) console.log(resultArr)
說回原理,代碼的原理在於 對於對象類數據,值的存儲不是存放在棧中,而是存儲在堆中,let obj = {} 實際上obj 的真實信息是這個存在與堆中的,而obj實際存儲的是這個對象的地址,而使用obj時我們是根據在obj所獲取的地址,找到對應的堆數據進行修改。同樣的,在上述代碼中,我們雖然沒有直接修改 resultArr ,但我們通過修改 obj[code] 的值,對於引用obj[code] 的resultArr而言,其內值已經發生變化。簡單代碼如下
let obj1 = { name:‘張三‘, } let obj2 = obj1 obj2.name = ‘李四‘ console.log(obj1.name) // 李四
詳細內容可以百度或者谷歌搜索 js對象的賦值的引用
參考資料:JavaScript高級程序設計 第四章 4.1.2 復制變量值
JavaScript巧用對象的引用解決三級聯動