不使用Proxy动态创建对象属性?结合Immutable.js的场景需求
不用Proxy实现选择器函数转Immutable属性路径数组
嘿,其实你根本不需要用Proxy来搞定这个需求!你的核心目标是把那种用来选取嵌套属性的选择器函数,转换成Immutable.js的setIn/updateIn需要的属性路径字符串数组对吧?下面给你两个完全不用Proxy的可行方案:
方案1:解析选择器函数字符串(适合静态属性场景)
如果你的选择器都是像obj => obj.a.b.c这种简单的静态属性访问形式,直接解析函数的字符串内容就能提取路径:
function getSelectorPath(selector) { const funcStr = selector.toString(); // 匹配箭头函数和普通函数里的属性访问链 const pathMatch = funcStr.match(/obj(\.[a-zA-Z_$][\w$]*)*(?=\s*[;}])/); if (!pathMatch) { throw new Error('没法解析这个选择器哦,请确保是简单的属性访问形式~'); } return pathMatch[0].split('.').slice(1); } // 用例测试 const nameSelector = obj => obj.user.profile.name; console.log(getSelectorPath(nameSelector)); // 输出 ["user", "profile", "name"] const ageSelector = function(obj) { return obj.user.age; }; console.log(getSelectorPath(ageSelector)); // 输出 ["user", "age"]
这个方案兼容性拉满(ES3就能跑),但有个小局限:只能处理静态的直接属性访问,如果选择器里有条件判断、计算属性名(比如obj['user-' + id])或者函数调用这类复杂逻辑,就没法正确解析了。
方案2:调整选择器写法,用路径构建器(通用兼容)
如果你的选择器可能有复杂逻辑,或者想更稳妥地追踪路径,可以稍微调整下选择器的写法,让它接收一个路径构建器,而不是直接访问对象:
// 造一个路径构建器 function createPathBuilder() { const path = []; return { get(prop) { path.push(prop); return this; // 支持链式调用 }, getPath() { return [...path]; } }; } // 调整后的选择器:调用builder的get方法来构建路径 const nameSelector = builder => builder.get('user').get('profile').get('name'); const ageSelector = builder => builder.get('user').get('age'); // 转换函数 function selectorToPath(selector) { const builder = createPathBuilder(); selector(builder); return builder.getPath(); } // 测试一下 console.log(selectorToPath(nameSelector)); // 输出 ["user", "profile", "name"]
这个方案完全不依赖Proxy,而且能支持各种复杂的路径逻辑(比如根据条件选不同属性),唯一的小代价就是需要调整选择器的写法——从直接访问对象改成调用构建器的方法。
回到你最开始的问题:你问不用Proxy能不能动态创建对象属性,其实针对你的实际需求,根本不需要动态创建属性,上面两个方案都能完美解决你把选择器转成Immutable路径数组的问题~
内容的提问来源于stack exchange,提问作者Rico Kahler
相关产品推荐
相关产品推荐

