JavaScript中无法覆盖父类构造函数参数默认值,必须由父类用??安全处理undefined;子类应原样传参,避免提前赋默认值;类体默认值与参数默认值可共存但需注意覆盖优先级。

JavaScript 中不存在“覆盖父类构造函数参数”这个操作——参数本身不能被覆盖,真正需要关注的是:如何让子类调用父类构造函数时,不破坏父类内部设定的默认值逻辑。
父类必须自己处理 undefined
默认值逻辑必须实现在父类构造函数内部,子类无法“继承”或“覆盖”参数默认值。父类要用安全方式判断缺失:
- 推荐用 ?? 操作符:this.name = name ?? 'Unknown'
- 避免用 ||,否则会误判 0、false、'' 等 falsy 值
- 引用类型(如数组)每次新建:this.items = items ?? [],而不是复用字面量
子类调用 Parent.call 时别提前赋默认值
子类接收参数后,应原样或加工后传给父类,而不是在传参前就自行补默认值:
- ✅ 正确:Parent.call(this, name, age) —— 若 name 是 undefined,父类 ?? 仍生效
- ❌ 错误:const finalName = name || 'Dog'; Parent.call(this, finalName, age) —— 父类收不到 undefined,默认逻辑失效
- ⚠️ 解构也要小心:constructor({ name } = {}) { Parent.call(this, name) } 安全;但写成 constructor({ name = 'Pet' } = {}) { Parent.call(this, name) } 就提前覆盖了原始意图
类体默认值和构造函数参数默认值可共存但需注意优先级
ES2022 支持类属性直接赋默认值(如 name = 'guest'),它发生在 constructor 执行前;而构造函数参数默认值(如 constructor(name = 'anon'))只在实参为 undefined 时触发:
立即学习“Java免费学习笔记(深入)”;
- 若构造函数里写了 this.name = name,就会覆盖类体默认值
- 若想 fallback 到类体值,得手动写:this.name = name ?? this.name(注意 this 在 constructor 中才可用)
- 更清晰的做法:类体默认值用于纯字面量兜底,构造函数负责接收并校验外部输入
原型继承不影响默认值逻辑
只要子类在构造函数中调用了 Parent.call(this, ...),无论用 extends 还是 Object.create(Parent.prototype),父类的默认值逻辑都照常工作:
- 原型链只负责方法复用,不参与实例属性初始化
- 默认值属于构造函数执行阶段,只在 call/apply 调用时求值
- 组合继承(构造函数初始化 + 原型方法共享)天然支持这一机制


















