object.create(null) 创建无原型对象,[[prototype]] 为 null,不继承 tostring、hasownproperty 等方法,适用于哈希表、配置对象等需纯净键值对的场景。

用 Object.create(null) 创建的是一个**没有原型(即 [[Prototype]] 为 null)的对象**,它不继承任何内置方法(比如 toString、hasOwnProperty、constructor 等),和普通对象(如 {} 或 Object.create(Object.prototype))有本质区别。
为什么需要无原型对象?
常见于需要“纯净键值对容器”的场景,避免属性名与原型链上的方法冲突:
- 实现哈希表、映射缓存时,防止用户传入
"toString"、"constructor"这类字符串作为 key 导致意外覆盖或调用原型方法 - 构建配置对象、路由表、事件监听器注册表等,要求 key 完全自由、无隐式行为
- 某些底层工具库(如 Vue 的响应式系统早期版本)用它避免原型干扰
和普通空对象 {} 的关键区别
对比一下:
const obj1 = {};
const obj2 = Object.create(null);
console.log(obj1.toString); // ✅ function toString() { ... }
console.log(obj2.toString); // ❌ undefined
console.log(obj1.hasOwnProperty); // ✅ function hasOwnProperty() { ... }
console.log(obj2.hasOwnProperty); // ❌ undefined
console.log(Object.getPrototypeOf(obj1)); // → Object.prototype
console.log(Object.getPrototypeOf(obj2)); // → null
使用时的注意事项
因为没原型,很多常用操作不能直接用,需手动处理:
-
判断是否包含某个 key:不能用
obj.hasOwnProperty(key),改用Object.prototype.hasOwnProperty.call(obj, key)或更安全的Object.hasOwn(obj, key)(ES2022+) -
遍历所有自有属性:
for...in依然可用(它只遍历可枚举自有属性,不依赖原型链),但推荐用Object.keys(obj)—— 注意:它在Object.create(null)对象上仍能正常工作,因为是静态方法 -
不能直接调用 toString():若需字符串表示,可用
JSON.stringify(obj),或显式绑定:Object.prototype.toString.call(obj)
实用小技巧:安全地添加/检查属性
写个辅助函数让操作更直观:
const map = Object.create(null);
// 安全设值
function set(obj, key, value) {
obj[key] = value;
}
// 安全查值(避免原型污染风险)
function has(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
// 安全取值
function get(obj, key, defaultValue) {
return has(obj, key) ? obj[key] : defaultValue;
}
set(map, 'user-id', 123);
console.log(has(map, 'user-id')); // true
console.log(get(map, 'user-id')); // 123
不复杂但容易忽略:无原型对象不是“更高级”的对象,而是更干净的白板——用对了场景很有力,乱用反而会让代码难维护。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











