我有一个如下所示的命名空间生成器:(作为一项要求,它还需要具有原型对象 extra 和 default )。
function generateNamespace(staticMethods, prototypeMethods){
var namespace = function(){}; //create namespace
/**add staticMehods and prototypeMethods to namespace*/
extend(namespace, staticMethods); //extend function from NojeJS
extend(namespace.prototype, prototypeMethods);
//create extra and default objects.
namespace.prototype.default = namespace.prototype.default || {};
namespace.prototype.extra = namespace.prototype.extra || {};
return namespace;
}
我们的想法是生成如下命名空间:
var protObj = {id: function(){
console.log("id");
}
}
var myNameSpace = generateNamespace({}, protObj);
当我实例化时:
var instanceOfmyNameSpace = new myNameSpace();
结果包含函数id
,以及对象default
和extra
。
但如果我跑:
var instance2 = new myNameSpace({test: "foo"});
然后:assert.equal(instance2, instanceOfmyNameSpace) \\=true
这意味着(?)给定对象被忽略。
例如,我需要做什么才能将该对象与default
对象合并?完美的输入/输出将是:
//input
var instance2 = new myNameSpace({test: "foo"});
//output
console.log(instance2.default.test) \\-> "foo"
更新,答案
我需要做的就是将namespace
创建为constructor
,然后将staticMethods
和prototypeMethods
添加到其中:
var extend = require('util')._extend;
function generateNamespace(staticMethods, prototypeMethods){
var namespace = function(defaults, extras){
this.default = extend({}, this.constructor.default, defaults);
this.extra = extend({}, this.constructor.extra, extras);
}
extend(namespace, staticMethods);
extend(namespace.prototype, prototypeMethods);
return namespace;
}
答案 0 :(得分:0)
您的代码并未显示您如何将prototypeMethods
甚至staticMethods
复制到namespace
,这使得难以回答问题。我通常使用复制功能来执行这些操作。它适用于静态和原型方法。
这是mixin / copy函数:
var mixin = function (obj, mixins) {
var keys = Object.keys(mixins);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
obj[key] = mixins[key];
}
};
你会像以下一样使用它:
function generateNamespace(staticMethods, prototypeMethods){
var namespace = function () {}; //create namespace
// copy staticMethods to namespace
mixin(namespace, staticMethods);
// copy prototype members
mixin(namespace.prototype, prototypeMethods);
//create extra and default objects.
namespace.prototype.default = namespace.prototype.default || {};
namespace.prototype.extra = namespace.prototype.extra || {};
return namespace;
}
另请注意,使用行namespace = function(){}; //create namespace
,您需要像我在声明var
时所做的那样添加namespace
,否则变量将变为全局变量,并且可能会出现意外行为。