You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:15:23