我相信您正在寻找的是 node.js 所指的“模块”,在http://nodejs.org/api/modules.html中有解释
一种方法是创建一个名为“Airplane.js”的新文件,其中包含:
// define your main object
var Airplane = function(){
// initialize it here
};
Airplane.funcOne=function(){ // "class" level function
};
Airplane.prototype.funcTwo=function(){ // "instance" level function
};
// assign Airplane to module exports
module.exports=Airplane;
// which allows you to:
// var Airplane=require('Airplane');
如果您不希望在其他代码中使用您的引擎,您可以在 Airplane.js 中定义它。
如果您希望您需要从其他代码中“要求”它,您可能希望将其放入它自己的文件中并在 Airplane.js 中“要求”它,例如:
// Engine.js
var Engine=function(){
};
module.exports=Engine;
// Airplane.js
var Engine=require('Engine');
var Airplane=function(){
};
module.exports=Airplane;
最后,如果您想从同一个文件中同时公开 Airplane 和 Engine,您可以:
var Engine=function(){
};
var Airplane=function(){
};
module.exports={
Engine: Engine,
Airplane: Airplane
};
因此,当您在另一个文件中需要 Airplane 时,您会说:
var Airplane = require('Airplane').Airplane,
Engine = require('Airplane').Engine;
更新
作为记录,我不赞成在定义对象的文件之外定义对象的原型方法,但话虽如此......
将另一个文件中定义的方法添加到现有对象需要您“需要”附加文件,迭代其函数,并将它们添加到现有对象。
最简单的方法是将您的方法定义为:
// file: AirplaneMethods.js
module.exports={
// what occurs in situation1
situation1: function(){
// as expected, 'this' within this method refers
// to the object into which this method is "imported."
return this; // to facilitate method chaining
},
// what occurs in situation2
situation2: function(){
// ...
return this;
}
// etc.
};
然后,要将这些方法添加到您的 Airplane 对象,您将:
var Airplane=function(){
// initialization
};
var importedMethods=require('AirplaneMethods');
for(var methodName in importedMethods) {
Airplane.prototype[methodName]=importedMethods[methodName];
}
或者对于更通用的解决方案:
/* Import.js -- 20130712 raisch
*
* imports methods defined in one or more external paths into an
* existing object's prototype
*
* Usage:
*
* var Import=require('Import');
*
* var Thing=function() {};
*
* Import.from(path1,path2,...).into(Thing);
*
* -or-
*
* Import.into(Thing).from(path1,path2,...)
*
*/
var util=require('util'),
assert=require('assert');
var Import=module.exports=function(){};
Import._target=null;
Import._libs={};
// shortcut
var hasOwnProperty=Object.prototype.hasOwnProperty;
// helper
function isEmpty(obj){
var result=true;
if(obj===null || 0===obj.length) {
result=true;
}
else if(obj.length && obj.length>0) {
result=false;
}
else {
for(var k in obj) {
if(hasOwnProperty.call(obj,k)) {
result=false;
break;
}
}
}
return result;
}
/**
* requires one or more libs, caching them into self._libs
*
* if self._target is not null, calls self.into() to add all lib
* methods to self._target.prototype
*
* @param paths {Array<String>}
* @returns {Object} self
*/
Import.from=function from(/*path,...*/){
var paths=Array.prototype.slice(arguments);
for(var i=0, len=paths.length; i<len; i++){
var path=paths[i],
lib=null;
try{
lib=require(path);
if(isEmpty(lib)){
throw 'requiring "'+path+'" did not produce a useful object';
}
}
catch(e){
console.error('Import.from failed to require path "%s":%s', path, e);
continue;
}
this._libs[path]=lib;
}
this._target && this.into(this._target);
return this;
};
/**
* sets target object (class) into which to import lib methods
*
* if self._libs is not empty, adds all lib methods to self._target.prototype
*
* @param target {Object} into which to import
* @returns {Object} self
*/
Import.into=function into(target){
assert.ok(target.prototype, 'Import.into: target must have a prototype');
this._target=target;
if(!isEmpty(this._libs)){
for(var libname in this._libs){
var lib=this._libs[libname];
for(var name in lib){
this._target.prototype[name]=lib[name];
}
}
}
return this;
};
/**
* clears library cache
* @returns {Object} self
*/
Import.clear=function clear(){
this._libs={};
return this;
};
/**
* clears library cache and target object
* @returns {Object}
*/
Import.reset=function reset(){
delete this._target;
this.clear();
return this;
};