Kikobeats/null-prototype-object · 文件 下载 ZIP
文件最后提交记录最后更新时间
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈
null-prototype-object
一个用于使用可复用构造函数创建**
null原型的对象**的最小工具。
为什么不直接使用 Object.create(null)
Object.create(null) 会给你一个没有原型的干净对象——适用于:
- 安全的键值映射
- 避免继承的方法(
toString、hasOwnProperty等) - 防止原型污染
但在高频场景下存在性能开销。
问题所在
每次调用 Object.create(null) 都会创建一个新的对象形状(隐藏类)。
像 V8 这样的 JavaScript 引擎无法优化重复使用,因为:
- 原型未被共享
- 形状无法复用
- 内联缓存和 JIT 优化失效
- 导致多态调用点(去优化触发器)
解决方案:null-prototype-object
此包提供了一个具有冻结的、共享的空原型的构造函数,使 V8 能够:
- 复用稳定的隐藏类
- 内联属性访问
- 优化内存布局
- 避免动态形状转换
为什么它更快
| 特性 | Object.create(null) | new NullProtoObj() |
|---|---|---|
| 共享原型 | ❌ | ✅ |
| 隐藏类复用 | ❌ | ✅ |
| 内联缓存 | ❌ | ✅ |
| 对 JIT 友好 | ❌ | ✅ |
| 内存高效 | ❌ | ✅ |
何时使用它
在以下情况下使用 null-prototype-object:
- 你正在分配许多 null-prototype 对象(例如解析器、序列化器、缓存)。
- 你希望在紧密循环中获得可预测的性能。
- 你正在优化热代码路径中的对象创建。
安装
$ npm install null-prototype-object --save
用法
const NullProtoObj = require('null-prototype-object')
const obj = new NullProtoObj()
// No inherited methods
console.log(obj.toString) // undefined
// Safe for dictionary-style use
obj.__proto__ = 'polluted? nope'
console.log(obj.__proto__) // => "polluted? nope"
console.log(obj.foo)
obj.foo = 'bar'
console.log(Object.getPrototypeOf(obj)) // ==> null (via prototype chain)
基准测试
NullProtoObj via constructor x 207,586,282 ops/sec ±4.80% (81 runs sampled)
Object.create(null) x 54,415,324 ops/sec ±2.01% (89 runs sampled)
{} (normal object) x 194,340,713 ops/sec ±5.15% (77 runs sampled)
{__proto__:null} x 39,313,923 ops/sec ±2.37% (92 runs sampled)
Fastest is NullProtoObj via constructor
许可证
null-prototype-object © Kiko Beats,基于 MIT 许可证发布。
感谢 pi0 和 anonrig。由 Kiko Beats 维护,并得到 contributors 的帮助。
kikobeats.com · GitHub Kiko Beats · Twitter @kikobeats