使用 object.create(null) 创建纯空对象作为根仓库可杜绝原型污染,通过点号路径动态构建嵌套命名空间,每级子空间仍为 null 原型,保障隔离性、安全性和内存效率。

用 Object.create(null) 创建纯空对象作为根仓库,再通过分层委托链实现命名空间隔离,是轻量、安全且可扩展的方案。
用 null 原型杜绝原型污染
普通对象(如 {})继承自 Object.prototype,会意外暴露 toString、hasOwnProperty 等方法,导致键名冲突或被覆盖。使用 Object.create(null) 创建“无原型”对象,从根源上消除干扰:
const warehouse = Object.create(null); // 没有 __proto__,没有 toString,没有 constructor
warehouse['user.login'] = () => { /* ... */ };
warehouse['config.api.url'] = 'https://api.example.com';
// 即便 key 是 'toString',也不会被原型方法遮蔽
warehouse.toString = 'custom'; // 安全赋值
按点号路径自动构建嵌套命名空间
将带点的字符串(如 'db.connection.pool')解析为嵌套结构,并逐级创建中间对象(但保持顶层仍是 null 原型):
- 不直接在
warehouse上挂整个嵌套对象,而是动态解析路径、惰性创建子空间 - 每一级子空间仍用
Object.create(null),确保隔离性延续 - 避免提前创建冗余层级,节省内存
function define(warehouse, path, value) {
const parts = path.split('.');
let current = warehouse;
for (let i = 0; i define(warehouse, 'auth.token.refresh', () => { /<em> ... </em>/ });
define(warehouse, 'auth.user.profile', { name: 'Alice' });<p>// 使用时:warehouse.auth.token.refresh()
</p>支持只读命名空间与访问控制
对特定命名空间(如 'constants' 或 'env')冻结其结构,防止运行时篡改:
- 用
Object.freeze()锁定某一层子空间(不影响其下未冻结的子空间) - 结合
Object.defineProperty设置不可枚举、不可配置的属性,隐藏内部结构 - 导出只读代理(
Proxy)供外部消费,仓库本体保留在模块私有作用域中
// 冻结 constants 命名空间
warehouse.constants = Object.create(null);
warehouse.constants.API_TIMEOUT = 5000;
warehouse.constants.MAX_RETRY = 3;
Object.freeze(warehouse.constants); // 无法增删改
<p>// 只读代理(可选)
const readOnlyWarehouse = new Proxy(warehouse, {
set() { return false; }, // 禁止写入
deleteProperty() { return false; }
});
</p>配套工具:路径查询、批量注册与命名空间快照
增强可用性,让大型仓库易维护:
-
路径查询:提供
get(warehouse, 'a.b.c')安全取值(支持默认值、避免报错) -
批量注册:接受形如
{ 'ui.button.theme': 'dark', 'ui.input.size': 'large' }的扁平对象,自动解析并注入 -
快照导出:生成当前所有已定义路径的数组(
['auth.token.refresh', 'config.db.host']),便于调试和文档生成
function get(obj, path, defaultValue) {
const parts = path.split('.');
let current = obj;
for (const p of parts) {
if (current == null || typeof current !== 'object' || !(p in current)) {
return defaultValue;
}
current = current[p];
}
return current;
}










