util.inherits已废弃,仅浅拷贝父原型可枚举属性到子原型,不调用父构造函数、不修复constructor、不支持super和静态方法,应改用ES6 class extends。

Node.js 早期(v0.x 时代)常用 util.inherits 实现“伪经典继承”,它本质是把父构造函数的原型方法“浅拷贝”到子构造函数的原型上,**不支持 ES6 的 class、super 或现代原型链语义**,仅用于兼容老代码。现在已废弃(自 Node.js v10 起标记为 deprecated),不应在新项目中使用。
util.inherits 做了什么
它只做一件事:将父构造函数的 prototype 对象上的所有可枚举属性,赋值给子构造函数的 prototype。它不调用父构造函数,也不处理实例属性、this 绑定或 constructor 指向修复。
- 底层调用的是
Object.setPrototypeOf(child.prototype, parent.prototype)(Node.js v8+),但早期版本用的是属性遍历复制 - 不会自动设置
child.prototype.constructor,需手动修正,否则子实例的constructor仍指向父构造函数 - 无法继承静态方法(即构造函数自身的属性),只继承原型链上的方法
典型用法(已过时,仅作理解)
下面是一个常见写法示例:
class extends)
const util = require('util');
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a sound.`);
};
function Dog(name, breed) {
Animal.call(this, name); // 手动调用父构造函数初始化实例属性
this.breed = breed;
}
util.inherits(Dog, Animal); // 建立原型链:Dog.prototype.__proto__ === Animal.prototype
// 修复 constructor 指向(否则 Dog.prototype.constructor === Animal)
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
console.log(`${this.name} barks!`);
};
为什么它“老旧”且被弃用
- 语义模糊:不是真正的“继承构造函数”,只是挂原型,容易误解为类似 Java 的继承机制
- 缺失关键能力:无法访问父类同名方法(无 super)、不支持静态继承、不兼容 new.target 和 Reflect.construct
-
与 ES6 不兼容:和
class、extends、super()无法混用,且 V8 引擎对 class 的优化远优于手工原型操作 - Node.js 官方明确弃用:文档标注为 “Deprecated since: v10.0.0”,推荐改用 ES2015+ 语法
现代替代方案(推荐)
直接使用原生 JavaScript 的 class 语法:
立即学习“Java免费学习笔记(深入)”;
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 正确调用父构造函数
this.breed = breed;
}
bark() {
console.log(`${this.name} barks!`);
}
}
该写法在所有现代 Node.js 版本(v14+)中开箱即用,语义清晰、调试友好、支持 super、静态方法继承、且被引擎深度优化。


















