Nodejs 请教关于require和继承的问题

Nodejs 请教关于require和继承的问题

我现在想写一个模块,由于模块逻辑相对复杂,模块内部有很多文件,我使用类似OOP方式来组织这个模块,比如一个父类下面有N个子类,这些子类和父类之间仅仅是一些细致行为不同 Node中使用exports和require可以得到父类的对象,那么继承的代码是怎么写的呢?

示例代码如下:

person.js

Person = function () {

}

Person.prototype.hello = function () { console.log(‘I am Person’); }

exports.Person = Person;

student.js

var person = require('./person');
var util = require('util');


function Student () {
	person.call(this);
}

util.inherits(Student, person);


Student.prototype.say = function() {
	console.log('I am student');
}


exports.Student = Student;

test.js

person = require('./person');
student = require('./student');


person.hello();
student.hello();
student.say();

这个基本上参照 http://cnodejs.org/topic/4fbae57dd46624c476072445 这个帖子来实现的,很诡异的报错了,求指导

util.js:538 ctor.prototype = Object.create(superCtor.prototype, { ^ TypeError: Object prototype may only be an Object or null at Function.create (native) at Object.exports.inherits (util.js:538:27)


9 回复

对于你遇到的问题,错误信息 TypeError: Object prototype may only be an Object or null 提示我们在使用 util.inherits 方法时,传递给它的参数类型不正确。根据 Node.js 的文档,util.inherits 需要两个构造函数作为参数,但你的代码中,你传递的是构造函数和对象。

我们可以通过直接使用原型链的方式来进行继承,而不需要依赖 util.inherits。以下是修改后的代码:

person.js

function Person() {
    // 初始化逻辑
}

Person.prototype.hello = function () {
    console.log('I am Person');
};

module.exports = Person;

student.js

const Person = require('./person');

function Student() {
    Person.call(this);  // 调用父类构造函数
}

// 继承父类的原型
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

// 添加子类独有的方法
Student.prototype.say = function() {
    console.log('I am student');
};

module.exports = Student;

test.js

const Person = require('./person');
const Student = require('./student');

const person = new Person();
const student = new Student();

person.hello();  // 输出 "I am Person"
student.hello(); // 输出 "I am Person"(因为继承了Person的方法)
student.say();   // 输出 "I am student"

通过这种方式,我们避免了使用 util.inherits,而是直接操作原型链,这样可以确保正确的继承关系。注意在设置子类原型时,我们还需要将 constructor 指回 Student,以保持构造函数的正确性。


var person = require(’./person’).person

感谢回复,这个似乎解决了上一个报错,但是貌似没继承成功,在test中调用student.hello()时报这个方法不存在

明白了,test中应该new这个对象

最后test中代码这样可以运行

person = require('./person');
student = require('./student');

p = new person.Person; p.hello();

s = new student.Student s.hello(); s.say();

什么样情况下需要new操作,什么样情况直接require就能用呢?为什么有些不用new呢,比如内置的http.xxx()就能工作

  • 你需要从一个构造函数对象(function{})构造一个对象的时候就得用new
  • 呃,你是不是对js和node.js不熟啊?建议先了解一下require机制,以及exports和module.exports

我的理解:

不用 new,就没有 新的对象(instance)产生,就没有 this, 就没有 prototype, 就没有继承的函数。因为继承的函数都在对象的 prototype 里面。

呃,这个,其实没有new,也有this和prototype的

http.createServer()相当于一个快捷方式,内部是有new Server()的,你可以看一下它的源码

你遇到的错误是因为在 util.inherits 方法中传入了错误的对象。util.inherits 需要传入构造函数,而不是构造函数的实例或对象。

你可以修改 student.js 文件中的继承部分,确保正确地使用 util.inherits 方法。以下是修正后的代码:

person.js

function Person() {
    // 初始化代码
}

Person.prototype.hello = function () {
    console.log('I am Person');
};

module.exports = { Person };

student.js

const { Person } = require('./person');
const util = require('util');

function Student() {
    Person.call(this); // 调用父类构造函数
}

util.inherits(Student, Person);

Student.prototype.say = function() {
    console.log('I am student');
};

module.exports = { Student };

test.js

const { Person } = require('./person');
const { Student } = require('./student');

const person = new Person();
const student = new Student();

person.hello();  // 输出 "I am Person"
student.hello(); // 输出 "I am Person"
student.say();   // 输出 "I am student"

关键点解释:

  1. module.exports: 使用对象形式导出,使得其他模块可以方便地导入。
  2. Person.call(this): 在 Student 的构造函数中调用父类 Person 的构造函数,以便初始化父类的属性。
  3. util.inherits: 正确地使用 util.inherits 方法,传入两个构造函数。

通过以上修改,你应该可以避免之前遇到的错误,并且正确地实现继承。

回到顶部