
本文详解如何将 json 文件中存储的类型名称字符串(如 "number"、"string")安全、准确地映射为对应 javascript 原生构造函数或类型标识,从而在运行时动态创建实例或执行类型检查。
在 JavaScript 中,JSON 本身不支持存储函数、构造器或原始类型对象——它仅能序列化基本值(字符串、数字、布尔值、null、数组、对象)。因此,当你从 types.json 中读取 "number" 或 "string" 时,得到的永远是字符串字面量,而非 Number 构造函数或 String 类型本身。直接赋值 myObject.numberType = types.type1 不会获得 number 类型行为,而只是保存了一个字符串 "number"。
要实现“从字符串名还原为可操作的类型”,核心思路是建立一个受控的类型名称到构造函数/类型的映射表,而非尝试危险的 eval() 或 Function() 动态执行。
✅ 推荐方案:白名单式类型映射
以下是一个健壮、安全且可扩展的实现方式:
// types.json
{
"type1": "number",
"type2": "string",
"type3": "boolean",
"type4": "array"
}import types from './types.json' assert { type: 'json' };
// ✅ 白名单映射:仅允许预定义的安全类型
const TYPE_MAP = {
'number': Number,
'string': String,
'boolean': Boolean,
'array': Array,
'object': Object,
'null': () => null,
'undefined': () => undefined
};
function resolveType(typeName) {
const Constructor = TYPE_MAP[typeName.toLowerCase()];
if (!Constructor) {
throw new Error(`Unsupported type name: "${typeName}"`);
}
return Constructor;
}
// 使用示例
const myObject = new MyObject();
myObject.numberType = resolveType(types.type1); // → Number 构造函数
myObject.stringType = resolveType(types.type2); // → String 构造函数
myObject.main();? 提示:resolveType("number") 返回的是 Number 构造函数(即 typeof Number === 'function'),可用于 new Number(42) 或 Number.isInteger() 等;若需类型判断,应配合 typeof 或 instanceof 使用(例如 val instanceof resolveType('array'))。
⚠️ 注意事项与最佳实践
- 禁止使用 eval() 或 new Function():虽然 eval('Number') 可返回构造函数,但存在严重 XSS 和代码注入风险,且违反 CSP 安全策略,生产环境绝对禁用。
- 区分「类型名」与「类型判断」:JSON 中存的是类型标识符(如 "number"),不是值本身。你无法通过该字符串直接获得 42 这样的 number 值——它只用于指导后续逻辑(如验证、转换、实例化)。
- 支持自定义类型扩展:可在 TYPE_MAP 中添加业务类,例如 'user': User,前提是确保类已声明且可访问。
-
类型校验建议:在 MyObject.main() 内部,应基于 numberType 是否为函数来执行类型约束,例如:
main() { if (typeof this.numberType === 'function') { this.value = new this.numberType(this.rawValue); } }
✅ 总结
将类型信息外置到 JSON 是配置驱动开发的常见需求,但必须通过显式、可审计的映射机制桥接字符串与运行时类型。本文提供的 TYPE_MAP 方案兼顾安全性、可读性与可维护性,是现代 JavaScript(ESM + JSON modules)下的推荐实践。切记:永远不要信任外部输入直接执行代码,而应始终通过白名单控制类型解析边界。
立即学习“Java免费学习笔记(深入)”;










