国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

JavaScript 處理樹數據結構的方法示例

2024-05-06 15:37:55
字體:
來源:轉載
供稿:網友

JavaScript 處理樹結構數據

場景

即便在前端,也有很多時候需要操作 樹結構 的情況,最典型的場景莫過于 無限級分類。之前吾輩曾經遇到過這種場景,但當時沒有多想直接手撕 JavaScript 列表轉樹了,并沒有想到進行封裝。后來遇到的場景多了,想到如何封裝樹結構操作,但考慮到不同場景的樹節點結構的不同,就沒有繼續進行下去了。

直到吾輩開始經常運用了 ES6 Proxy 之后,吾輩想到了新的解決方案!

思考

問: 之前為什么停止封裝樹結構操作了?
答: 因為不同的樹結構節點可能有不同的結構,例如某個項目的樹節點父節點 id 字段是 parent,而另一個項目則是 parentId
問: Proxy 如何解決這個問題呢?
答: Proxy 可以攔截對象的操作,當訪問對象不存在的字段時,Proxy 能將之代理到已經存在的字段上
問: 這點意味著什么?
答: 它意味著 Proxy 能夠抹平不同的樹節點結構之間的差異!
問: 我還是不太明白 Proxy 怎么用,能舉個具體的例子么?
答: 當然可以,我現在就讓你看看 Proxy 的能力

下面思考一下如何在同一個函數中處理這兩種樹節點結構

/** * 系統菜單 */class SysMenu { /**  * 構造函數  * @param {Number} id 菜單 id  * @param {String} name 顯示的名稱  * @param {Number} parent 父級菜單 id  */ constructor(id, name, parent) {  this.id = id  this.name = name  this.parent = parent }}/** * 系統權限 */class SysPermission { /**  * 構造函數  * @param {String} uid 系統唯一 uuid  * @param {String} label 顯示的菜單名  * @param {String} parentId 父級權限 uid  */ constructor(uid, label, parentId) {  this.uid = uid  this.label = label  this.parentId = parentId }}

下面讓我們使用 Proxy 來抹平訪問它們之間的差異

const sysMenuMap = new Map().set('parentId', 'parent')const sysMenu = new Proxy(new SysMenu(1, 'rx', 0), { get(_, k) {  if (sysMenuMap.has(k)) {   return Reflect.get(_, sysMenuMap.get(k))  }  return Reflect.get(_, k) },})console.log(sysMenu.id, sysMenu.name, sysMenu.parentId) // 1 'rx' 0const sysPermissionMap = new Map().set('id', 'uid').set('name', 'label')const sysPermission = new Proxy(new SysPermission(1, 'rx', 0), { get(_, k) {  if (sysPermissionMap.has(k)) {   return Reflect.get(_, sysPermissionMap.get(k))  }  return Reflect.get(_, k) },})console.log(sysPermission.id, sysPermission.name, sysPermission.parentId) // 1 'rx' 0

定義橋接函數

現在,差異確實抹平了,我們可以通過訪問相同的屬性來獲取到不同結構對象的值!然而,每個對象都寫一次代理終究有點麻煩,所以我們實現一個通用函數用以包裝。

/** * 橋接對象不存在的字段 * @param {Object} map 代理的字段映射 Map * @returns {Function} 轉換一個對象為代理對象 */export function bridge(map) { /**  * 為對象添加代理的函數  * @param {Object} obj 任何對象  * @returns {Proxy} 代理后的對象  */ return function(obj) {  return new Proxy(obj, {   get(target, k) {    if (Reflect.has(map, k)) {     return Reflect.get(target, Reflect.get(map, k))    }    return Reflect.get(target, k)   },   set(target, k, v) {    if (Reflect.has(map, k)) {     Reflect.set(target, Reflect.get(map, k), v)     return true    }    Reflect.set(target, k, v)    return true   },  }) }}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 湖口县| 轮台县| 会泽县| 汝州市| 西畴县| 库车县| 清河县| 珲春市| 花莲县| 定边县| 邓州市| 福海县| 泸州市| 西丰县| 綦江县| 肥乡县| 浦北县| 旬邑县| 南通市| 广元市| 江口县| 白玉县| 雅江县| 彭州市| 社旗县| 杭锦后旗| 和龙市| 静乐县| 卓资县| 囊谦县| 忻城县| 离岛区| 岑巩县| 方正县| 蒲江县| 比如县| 固原市| 铁岭县| 铜梁县| 西平县| 泰宁县|