无需eval(),如何通过变量名引用对应的对象?
不用
eval()通过变量名引用对象的解决方案 好问题!你碰到的核心卡点是把对象的名称字符串和对象本身的引用搞混了——数组里存的'obj1'只是个字符串,不是指向obj1这个对象的引用,所以直接对字符串执行Object.assign肯定没用。下面给你两种安全靠谱的替代方案,彻底告别eval():
方案一:直接存储对象引用(最推荐)
既然你的目标是操作对象本身,完全没必要存它们的名称字符串,直接把对象放进数组里就行。这样遍历数组时拿到的就是真实的对象引用,操作自然会生效:
const obj1 = {}; const obj2 = {}; const obj3 = {}; // 直接存对象实例,不是字符串名称 const objects = [obj1, obj2, obj3]; // 遍历操作对象,正常生效 objects.forEach(obj => Object.assign(obj, { extended: true })); // 验证:obj1.extended 现在是 true console.log(obj1.extended); // true
这种方式完全符合JavaScript引用类型的特性,简洁又安全,是处理这类场景的首选。
方案二:用容器对象维护名称-对象映射(适合必须用字符串标识的场景)
如果因为业务需求(比如从外部获取到对象名称字符串),你必须通过字符串来关联对象,可以创建一个“容器”对象,把所有需要操作的对象都存进去,用对象的键对应原来的对象名称,之后通过键来访问对应的对象:
const obj1 = {}; const obj2 = {}; const obj3 = {}; // 构建名称到对象的映射表 const objectMap = { obj1: obj1, obj2: obj2, obj3: obj3 }; const objectNames = ['obj1', 'obj2', 'obj3']; // 通过映射表的键获取对象并操作 objectNames.forEach(name => { Object.assign(objectMap[name], { extended: true }); }); // 验证:obj2.extended 现在是 true console.log(obj2.extended); // true
这种方式相当于自己维护了一个可控的“名称-对象”字典,比eval()安全得多——eval()会执行任意传入的字符串,一旦字符串包含恶意代码(比如用户输入的内容),就会造成严重的安全风险;而这种方式只会访问你预先定义好的键,完全在掌控之中。
为什么要杜绝eval()?
你提到MDN明确说“绝对不要使用eval”,原因主要有三点:
- 安全风险:
eval()会解析并执行任意字符串,若字符串来自不可信来源(比如用户输入),很容易被注入恶意代码; - 性能问题:
eval()会绕过JS引擎的词法分析和优化,执行效率远低于普通代码; - 作用域混乱:
eval()会在当前作用域执行代码,容易导致变量污染和难以追踪的bug。
内容的提问来源于stack exchange,提问作者Dwayne
相关产品推荐
相关产品推荐

