原型链终点是null而非undefined,因null语义为“有定义但为空”,准确表达链终止;object.prototype非空对象,含基础方法且其__proto__为null;属性查找无自动兜底,默认值需开发者主动设计。

原型链里没有“空对象”这个概念,真正存在的是 Object.prototype —— 它是所有普通对象的顶层原型,本身不是空对象,而是包含 toString、hasOwnProperty 等基础方法的对象;它的 __proto__ 指向 null,这才是原型链的终点。
为什么终点是 null 而不是 undefined?
null 表示“有定义但值为空”,语义上准确表达了“原型链到此为止”;而 undefined 表示“未定义”,不符合设计意图——每个对象都必须有明确的 [[Prototype]] 链路,链尾必须是一个确定的终止标识。所以 Object.getPrototypeOf(Object.prototype) 返回的就是 null,不是 undefined,也不是 {}。
属性查找时的缺省行为是自动的,不是靠“空对象兜底”
JavaScript 不会为缺失属性自动填默认值。当你访问 obj.x 而 x 在实例和整个原型链上都不存在时,结果就是 undefined,不会跳转到某个“空对象”去取默认值。所谓“缺省策略”,实际要靠开发者主动设计:
使用 OpenAI Codex CLI 处理编码任务。触发词:codex、code review、fix CI、refactor code、implement feature、coding agent、gpt-5-codex。Clawdbot 可将编码工作委托给 Codex CLI 作为子代理或直接工具。
- 在构造函数中初始化实例属性(如
this.x = defaultX) - 在原型方法里做 fallback 判断(如
return this.x ?? this.constructor.defaultX) - 用 getter 封装访问逻辑(如
get x() { return this._x ?? 100; }) - 借助
Object.assign(this, defaults)或解构赋值统一补全初始状态
别误把 Object.prototype 当作可修改的“默认模板”
它虽是链顶,但不是用来塞默认值的地方。往 Object.prototype 上添加属性或方法,会影响**所有对象**(包括数组、日期等),极易引发冲突和不可预知行为。真正的默认策略应作用于具体类型层级:
- 在自定义类的
prototype上定义通用方法或只读默认值 - 用
Object.create(MyClass.prototype)创建实例时,确保原型对象已预置合理初始结构 - 若需实例删除后仍能回退,默认值应存在原型上,且实例不覆盖同名属性(即避免遮蔽)
遮蔽(shadowing)是控制缺省的关键机制
同名属性出现在实例上,就会屏蔽原型链上的同名项。这意味着:
- 设置
obj.name = 'Alice'后,即使MyClass.prototype.name = 'Unknown',读取obj.name也永远得到 'Alice' - 删除该属性(
delete obj.name)后,访问会自然回落到原型链,拿到 'Unknown' - 这种机制天然支持“实例优先,原型兜底”的缺省模型,无需额外判断










