object.create(null) 创建的对象没有 proto 属性且不继承任何原型方法,因其原型被显式设为 null,原型链彻底中断;验证方式包括 object.getprototypeof(obj)===null、'__proto__' in obj 为 false、obj.tostring 为 undefined 等。

直接使用 Object.create(null) 就能创建一个没有 __proto__ 属性、也不继承任何原型方法的绝对纯净对象。
为什么它“没 __proto__”?
普通对象(如 {} 或 new Object())默认以 Object.prototype 为原型,因此自带 __proto__ 访问器、toString、hasOwnProperty 等属性。而 Object.create(null) 显式指定原型为 null,意味着该对象的原型链在创建时就彻底中断——它既没有 __proto__ 属性,也没有任何继承来的方法或属性。
验证它确实“空”
你可以用几种方式确认它的纯净性:
-
Object.getPrototypeOf(obj) === null→ 返回true -
'__proto__' in obj→ 返回false(注意:不是undefined,是根本不存在该键) -
obj.toString→undefined(不像普通对象会继承Object.prototype.toString) -
obj.hasOwnProperty→undefined(无法直接调用,需用Object.prototype.hasOwnProperty.call(obj, 'key')替代)
典型使用场景
这种对象常用于需要完全可控键值对的场合,避免原型污染和意外属性干扰:
-
字典/映射表:比如缓存、配置项、事件监听器注册表,防止用户传入的 key 恰好是
toString、constructor等原型属性名 -
防冲突的哈希表:作为模块私有状态存储,确保
for...in遍历只返回你显式设置的键 - JSON Schema 或 AST 处理:解析结构化数据时,避免原型上同名方法被误触发
注意事项和替代写法
虽然纯净,但也失去便利性,使用时需额外小心:
- 不能直接调用
obj.hasOwnProperty(key),应改用Object.prototype.hasOwnProperty.call(obj, key) - 不能用
obj.toString(),需转成字符串时建议用JSON.stringify(obj)或手动构造 - ES6 的
Map更适合做键值容器(支持任意类型键、无原型干扰),但若只需字符串键且追求轻量,Object.create(null)仍是高效选择 - 不要混用:
Object.assign({}, obj)会把null原型对象“升级”回普通对象,丢失纯净性











