我希望能够从工厂构造实例并使它们看起来像void BST::find_sum(node * root1,node * root2,int sum)
{
if(root1==NULL)
return;
if(root2==NULL)
{
return;
}
if((root1->data+root2->data)==sum)
{
if(root1==root2)
return;
cout<<"\t "<<root1->data<<" + "<<root2->data<<" = "<<sum;
return;
}
find_sum(root1,root2->left,sum);
find_sum(root1,root2->right,sum);
return;
创建的实例 - 意味着构造函数和原型与new Instance()
创建的实例无法区分。 / p>
工厂将驻留在对象文字中,因此它的调用看起来像
new
请注意,“classname”“Instance”不会传递给通用创建者。
另一个要求是此var instance=App.factory.Instance.create(arg1,...);
的成员驻留在对象文字中,如果没有提供构造函数,则使用默认(无操作)。
驻留在文字中的成员是为了迭代和反思的目的,这就是为什么在白色空间中做任何事情的方法都不起作用。
Instance
我已经中途工作,但我感到困惑,并寻求基本方法的改进。另外,我是否缺少任何可以使/* jshint laxcomma: true */
window.App={
_name:'App'// convention
,factory:{
_name:'factory'
// begin specifying classes
,Instance:{ // this is a mini-factory of type 'Instance',
// a 'create' method is dynamically injected when 'factory' is initialized
_name:'Instance'
,ctor:function Instance(a,b){ // OPTIONAL specified constructor, want to ditch fn name here if possible
}
,template:{ // Instance spec container. Is like 'Instance.prototype'
//_name:'template' // convention, but will not be a member of 'instance'
valueMember:'something' // this will exist on finished 'prototype'
,funcMember:function(){ // this will exist on finished 'prototype'
}
}
,_static:{ // these will be placed on 'Instance' (constructor)
_name:'_static' // convention, but not placed
,valueMember:'something' // this will exist on 'Instance' (constructor)
,funcMember:function(){ // this will exist on 'Instance' (constructor)
}
}
//,create:function(){} is injected during init of factory
}// - Instance
// more classes like Instance here...
}
};
App.factory.Instance.create=function(){ // this must be generic/agnostic to 'Instance'
var that=this; // this is 'Instance:'
function init(){
if (that.ctor===undefined) { // user did not provide constructor
//that.ctor=new Function(''); // BAD WAY
// make a generic constructor with correct name
that.ctor=eval('(function '+that._name+'(){})');
}
// preserve constructor for reuse
that._ctor=that.ctor;
delete that.ctor;
var i;
if (typeof that._static==='object') { // put statics on constructor
for (i in that._static) {
if (i!=='_name') { // ignore convention
that._ctor[i]=that._static[i];
}
}
}
// doing it whole here, should be a cleaned-of-convention duplicate object
that._ctor.prototype=that.template;
that._ctor.name=that._name;
// this line confuses me, something should be done, do I need it?
//that._ctor.prototype.constructor=that._ctor; // produces 'constructor' in instance
}
// look in cache
if (that._ctor===undefined) {
init();
}
// NOW THE HARD PART - HOW TO INVOKE
var rv;
var fn=that._ctor;
//rv=construct(fn,arguments);
//rv= new fn();
rv=new that._ctor();
// HERE
// fn.prototype.constructor=fn;
// My problem at this point is getting instance.constructor to
// not be 'Object' but if I include the line above
// it shows 'constructor' as iterable
// however THIS LINE WORKS, but why? BUT Why do I have to do it here, after construction?
rv.constructor.prototype.constructor=that._ctor;
// NO that._ctor.prototype.constructor=that._ctor; puts 'constructor' on instance
return rv;
}; //-create
function Classic(a,b){
}
Classic.prototype.member="member";
var classic=new Classic();
var instance=App.factory.Instance.create();
console.log('classic',classic);
console.log('instance',instance);
console.log('classic.constructor',classic.constructor);
console.log('instance.constructor',instance.constructor);
console.log('instance.constructor.name',instance.constructor.name);
console.log('classic.constructor.name',classic.constructor.name);
与经典构造的对象区分开来的布线?
扩展这个想法,似乎应该有一个库,它将采用这样的模板并生成工厂,通过instance
构建类,从而提供更多控制 - 即Object.defineProperty
等语言内的一种语言
答案 0 :(得分:0)
,ctor:function Instance(a,b){ // OPTIONAL specified constructor, want to ditch fn name here if possible
如果您稍后创建name
等于_name
的{{1}}函数,可以在此处移除该类的名称,只需按ctor
<{1}} ctor.call(this);
App.factory.Instance.create=function(){ // this must be generic/agnostic to 'Instance'
看起来,为了与Instance
无关,您添加了_name
约定。您还可以创建一个函数来获取App
对象并递归添加_name
字段。另一种可能性是将factory
而不是Instance
传递给将要添加create
方法的函数。
that._ctor.name=that._name;
此代码不执行任何操作,因为函数的名称是只读属性。由于代码eval('(function '+that._name+'(){})')
已经使用您想要的名称创建了函数,因此也不需要它。
fn.prototype.constructor=fn
当您声明一个函数时,它会自动获取一个原型,并将构造函数字段设置为该函数。您必须使用rv.constructor.prototype.constructor=that._ctor;
设置原型的构造函数字段,因为您已使用模板替换原型。您可以在rv=new that._ctor();
之前或之后完成此操作。
classic instanceof Classic
instance instanceof App.factory.Instance
这将使您的工厂创建的对象与正常创建的对象区分开来。为了使instanceof
运算符工作App.factory.Instance
,需要使用构造函数。
以下是我提出的符合您要求的代码。
App = {
factory: {
Instance: {
template: {
c: 3,
d: 4
},
_static: {
e: 5,
f: 6
},
constructor: function (a, b) {
this.a = a;
this.b = b;
}
}
}
};
function init(factory) {
for (var name in factory) {
var constructor = eval('(function ' + name + '(){})');
constructor.prototype = factory[name].template;
Object.defineProperty(constructor.prototype, 'constructor', {
value: constructor,
enumerable: false
});
for (var property in factory[name]._static) {
constructor[property] = factory[name]._static[property];
}
var previous = factory[name].constructor;
var create = function () {
var instance = new constructor();
if (previous) {
previous.apply(instance, arguments);
}
return instance;
}
factory[name] = constructor;
factory[name].create = create;
}
}
init(App.factory);
function Classic(a, b) {
this.a = a;
this.b = b;
};
Classic.prototype.c = 3;
Classic.prototype.d = 4;
Classic.e = 5;
Classic.f = 6;
var classic = new Classic(1, 2);
var instance = App.factory.Instance.create(1, 2);
console.log('classic', classic);
console.log('instance', instance);
console.log('classic.constructor', classic.constructor);
console.log('instance.constructor', instance.constructor);
console.log('instance.constructor.name', instance.constructor.name);
console.log('classic.constructor.name', classic.constructor.name);
console.log('classic instanceof Classic', classic instanceof Classic);
console.log('instance instanceof App.factory.Instance', instance instanceof App.factory.Instance);
console.log('classic.a', classic.a);
console.log('classic.b', classic.b);
console.log('classic.c', classic.c);
console.log('classic.d', classic.d);
console.log('Classic.e', Classic.e);
console.log('Classic.f', Classic.f);
console.log('instance.a', instance.a);
console.log('instance.b', instance.b);
console.log('instance.c', instance.c);
console.log('instance.d', instance.d);
console.log('App.factory.Instance.e', App.factory.Instance.e);
console.log('App.factory.Instance.f', App.factory.Instance.f);
&#13;