JavaScript对象字面量中能否实现动态属性键?框架开发中的半动态对象生成疑问
问题根源与解决办法
嘿,你遇到的问题其实是个很容易踩的小坑——你的test变量根本不是你以为的“返回唯一值的函数”,而是一次性执行后就固定死的字符串!
看你定义test的代码:
const test = (function() { return String("morePlaceholderText" + getRandInt() ) })();
这里末尾的()直接把匿名函数执行了,所以test从一开始就变成了类似"morePlaceholderText7"的固定值,后面你在对象里写两次[test],本质上是给同一个属性名赋值,后面的内容自然会覆盖前面的,这就是为什么最终输出只有一个属性。
如何实现你想要的半动态对象?
你需要的是每次生成属性名时都调用函数生成新的唯一值,而不是只调用一次。这里有两种贴近你需求的简洁实现方式:
方式1:把test改成可重复调用的函数
把test定义成普通函数,然后在对象的计算属性位置主动调用它(一定要加()):
const validatorCache = new Set(); let max; function getRandInt() { let length = validatorCache.size; const initMax = 15; if(length < initMax){ max = initMax; } else { max++ }; const min = 1; let newRand; do { newRand = Math.floor(Math.random() * (max - min + 1)) + min; } while (validatorCache.has(newRand)); validatorCache.add(newRand); return newRand; }; // 去掉末尾的(),让test成为一个可重复调用的函数 const test = () => `morePlaceholderText${getRandInt()}`; // 每次生成属性名时调用test(),得到新的唯一值 let myObject = { [test()] : "placeholder text 1", [test()] : "lorem ipsum 2" }; console.log(JSON.stringify(myObject)); // 示例输出:{"morePlaceholderText3":"placeholder text 1","morePlaceholderText12":"lorem ipsum 2"}
这样每次[test()]都会触发一次函数调用,生成不同的属性名,就不会出现覆盖问题了。
方式2:直接在计算属性里写生成逻辑
如果不想单独定义test函数,也可以把逻辑直接写在计算属性里,更紧凑:
// 保留getRandInt和相关变量... let myObject = { [`morePlaceholderText${getRandInt()}`]: "placeholder text 1", [`morePlaceholderText${getRandInt()}`]: "lorem ipsum 2" };
为什么你之前的尝试没生效?
- 箭头函数没用对:你可能是把箭头函数赋值给
test后,直接写了[test]而不是[test()]——这样属性名会变成"() => ..."这个字符串,完全不是你想要的唯一值。 - 不加方括号的属性名:JS里对象字面量的属性名如果是表达式(比如函数调用),必须用方括号包裹,不然会被当成普通字符串,所以不加方括号肯定报错。
额外小技巧
如果之后需要批量生成多个这种动态属性,可以用循环来创建对象,效率更高:
const dynamicObj = {}; for(let i = 0; i < 5; i++){ dynamicObj[test()] = `content ${i}`; }
内容的提问来源于stack exchange,提问作者Neokythera
相关产品推荐
相关产品推荐

