我多年来一直主要是Perl编码员,但也有C ++背景,所以我来自一个经典的" OO背景,现在学习node.js.我刚读完The Principles of Object-Oriented JavaScript,它很好地向像我这样有经典思想的人解释了OO的JS概念。但是我留下了一个问题,特别是与node.js和继承有关。请原谅我,如果我还在使用" classic"词汇来解释我的问题。
假设我有一个模块lib/foo.js
:
function foo() {
console.log('Foo was called');
}
module.exports.foo = foo;
我想"子类"这在另一个模块lib/bar.js
中:
var foo = require('foo.js');
// Do some magic here with *.prototype, maybe?
function bar() {
console.log('Bar was called');
}
module.exports.bar = bar;
这样我的主脚本可以这样做:
var bar = require('lib/bar.js');
bar.foo(); // Output "Foo was called"
bar.bar(); // Output "Bar was called"
这甚至可能吗?如果是这样,我错过了什么?
或者这是一种反模式?或者根本不可能?我该怎么做呢?
答案 0 :(得分:2)
这是我如何做到的,以覆盖request module中的一种方法。 警告:许多节点模块的扩展设计很差,包括请求,因为它们在构造函数中做了太多的事情。不仅仅是一个巨大的参数选项,而是启动IO,连接等。例如,请求将http连接(最终)作为构造函数的一部分。没有明确的.call()
或.goDoIt()
方法。
在我的示例中,我想使用查询字符串而不是qs来格式化表单。我的模块巧妙命名为#34; MyRequest"。在名为myrequest.js的单独文件中,您有:
var Request = require('request/request.js');
var querystring = require('querystring');
MyRequest.prototype = Object.create(Request.prototype);
MyRequest.prototype.constructor = MyRequest;
// jury rig the constructor to do "just enough". Don't parse all the gazillion options
// In my case, all I wanted to patch was for a POST request
function MyRequest(options, callbackfn) {
"use strict";
if (callbackfn)
options.callback = callbackfn;
options.method = options.method || 'POST'; // used currently only for posts
Request.prototype.constructor.call(this, options);
// ^^^ this will trigger everything, including the actual http request (icky)
// so at this point you can't change anything more
}
// override form method to use querystring to do the stringify
MyRequest.prototype.form = function (form) {
"use strict";
if (form) {
this.setHeader('content-type', 'application/x-www-form-urlencoded; charset=utf-8');
this.body = querystring.stringify(form).toString('utf8');
// note that this.body and this.setHeader are fields/methods inherited from Request, not added in MyRequest.
return this;
}
else
return Request.prototype.form.apply(this, arguments);
};
然后,在您的应用程序中,而不是
var Request = require("request");
Request(url, function(err, resp, body)
{
// do something here
});
你去了
var MyRequest = require("lib/myrequest");
MyRequest(url, function(err, resp, body)
{
// do that same something here
});
我不是JavaScript大师所以可能有更好的方法......
答案 1 :(得分:0)
作为参考,我提出的具体解决方案是我的示例代码问题:
在lib/foo.js
:
var Foo = function() {}
Foo.prototype.foo = function() {
console.log('Foo was called!');
};
module.exports = new Foo;
在lib/bar.js
:
var foo = require('./foo.js');
var Bar = function() {}
Bar.prototype = Object.create(foo.__proto__);
Bar.prototype.constructor = Foo;
Bar.prototype.bar = function() {
console.log('Bar was called!');
};
module.exports = new Bar;
然后在我的测试脚本中:
var bar = require('lib/bar.js');
bar.foo(); // Output "Foo was called"
bar.bar(); // Output "Bar was called"