.agent/skills/pr_review/reference/object_create_null.md
Object.create(null) and Prototype Collision PreventionThis guide outlines the technical rules and evaluation criteria for using Object.create(null) versus standard object literals ({}) or Map in the Angular codebase.
Object.create(null) is AppropriateUsing Object.create(null) (or Map) is appropriate when all of the following conditions are met:
$locationShim, HTML sanitizer tag sets, or jsaction DOM event-type resolvers).map[key] !== undefined or key in map), where a key matching an Object.prototype member (such as 'toString', 'constructor', or 'hasOwnProperty') causes false positive matches or incorrect behavior.If an object receives untrusted dynamic keys and is exposed to public consumers or third-party code (e.g., SimpleChanges in ngOnChanges):
Object.create(null): Stripping Object.prototype from public objects is a breaking API change. Consumer code calling .hasOwnProperty(), .toString(), .valueOf(), or using string interpolation (`${obj}`) will fail at runtime (TypeError: obj.hasOwnProperty is not a function).Object.hasOwn(obj, key): Use Object.hasOwn for internal framework property lookups instead of direct index or in checks. This prevents prototype collision during internal reads without breaking the object's prototype for consumers.__proto__, constructor, prototype) when populating the object.Map or Custom Classes: For new public APIs requiring key-value stores with dynamic keys, prefer Map<K, V> or dedicated classes with explicit .get() and .has() methods.null is unavoidable, it must follow Angular's formal deprecation and major version breaking change process.Object.create(null) Should NOT Be UsedDo not replace {} with Object.create(null) in the following scenarios:
let sortedBreakpoints: {breakpoints?: number[]} = {}). Object.assign({}, ...) only copies own enumerable properties, so prototype properties on sources are never copied.tasksByHandleId: {[id: number]: Task}). Numeric keys do not collide with Object.prototype string members.const EMPTY_OBJECT = {} or const IN_PROGRESS_RESOLUTION = {}).{} literals use V8 fast hidden classes and monomorphic inline caching. Object.create(null) forces V8 dictionary mode and increases minified bundle size (e.g., in inline polyfills like event-dispatch-contract or SSR hydration bundles).