Object.create(null) 创建的对象无原型,不继承 Object.prototype 方法,调用 toString 等会报错,需用 Object.prototype.xxx.call 替代;扩展运算符、Object.keys 等仍可用;适用于纯净键值存储场景。

使用 Object.create(null) 创建的对象没有原型(即 __proto__ 为 null),因此不会从 Object.prototype 继承任何方法(如 toString、hasOwnProperty、valueOf 等)。这能彻底避免原型链查找带来的干扰,但同时也意味着你不能直接调用这些常用方法——必须显式处理或替换等价逻辑。
避免因缺失原型方法导致的运行错误
这类对象调用 obj.toString() 或 obj.hasOwnProperty(key) 会直接报错:TypeError: obj.toString is not a function。解决方式不是“恢复原型”,而是改用更底层、不依赖原型的方法:
- 用
Object.prototype.toString.call(obj)替代obj.toString() - 用
Object.prototype.hasOwnProperty.call(obj, key)替代obj.hasOwnProperty(key) - 用
Object.prototype.isPrototypeOf.call(obj, target)(若需判断原型关系,但通常不适用 null 原型对象) - 对简单类型检测,可改用
typeof或Array.isArray()等内置函数
谨慎使用扩展运算符和 Object 方法
像 {...obj}、Object.keys(obj)、Object.assign({}, obj) 这些操作在 Object.create(null) 对象上仍能正常工作,因为它们内部不依赖对象自身的原型方法,而是通过内部抽象操作遍历自有属性。但要注意:
-
JSON.stringify(obj)没问题,它只序列化自有可枚举属性 -
for...in循环依然有效(只遍历自身可枚举属性,无继承属性干扰) - 但
obj instanceof Object永远为false,不能用于类型判断
需要通用工具方法时,封装一层安全调用
如果项目中大量使用 null 原型对象,可预先定义工具函数,避免重复写 Object.prototype.xxx.call:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
const safe = {
toString: (obj) => Object.prototype.toString.call(obj),
hasOwn: (obj, key) => Object.prototype.hasOwnProperty.call(obj, key),
keys: (obj) => Object.keys(obj),
assign: (target, ...sources) => Object.assign(target, ...sources)
};
这样既保持了 null 原型的纯净性,又提升了代码可读性和复用性。
明确设计意图,避免误用场景
Object.create(null) 主要用于需要绝对干净键值存储的场景,比如:
- 实现 Map-like 缓存(避免用户传入
constructor、toString等恶意 key 冲突) - 构建 AST 节点、配置表、路由表等内部数据结构
- 替代
Map且需字符串 key 的轻量场景(注意:不支持非字符串键)
如果不是出于明确规避原型污染或性能/语义需求,普通对象仍推荐用字面量 {} 或 Object.create(Object.prototype),以获得完整的对象能力支持。

















