2016-09-19 79 views
8

比方说,我有构造函数Foo,BarQux。我如何创建一个带有代理链的新对象(使用这些构造函数),我可以动态地动态选择它?动态代理继承

例如,一个对象将拥有委托链FooBar
另一个对象将具有链条Foo - >Qux

function Foo() { 
    this.foo = function() { 
    console.log('foo'); 
    } 
} 

function Bar() { 
    this.bar = function() { 
    console.log('bar'); 
    } 
} 

function Qux() { 
    this.qux = function() { 
    console.log('qux'); 
    } 
} 

对象fooBar就能够调用foo()bar()。另一个对象fooQux将能够呼叫foo()qux()。等

+0

+为说而不是委派继承。你也应该填充我想的构造函数的原型。 – Redu

+3

对不起,有点困惑。你想做什么? – Neal

+0

你想建立链接的时候?当使用构造函数创建新实例时?如何创建一个'fooBar'对象? – nils

回答

6

您可以使用这些构造函数为混入:

var fooBar = {}; 
Bar.call(fooBar); 
Foo.call(fooBar); 

var fooQux = {}; 
Qux.call(fooQux); 
Foo.call(fooQux); 

但是,您可能想将其写为装饰,甚至返回修改的对象,而不是构造函数,因为你不能使用他们的原型反正。因此,一个更方便的模式将是

function withFoo(obj) { 
    obj.foo = function() { 
    console.log('foo'); 
    }; 
    return obj; 
} 

function withBar(obj) { 
    obj.bar = function() { 
    console.log('bar'); 
    }; 
    return obj; 
} 

function withQux(obj) { 
    obj.qux = function() { 
    console.log('qux'); 
    }; 
    return obj; 
} 

,这样就可以使用他们喜欢

var fooBar = withFoo(withBar({})); 
var fooQux = withFoo(withQux({})); 
+0

这会让你做'fooBar.bar()',不知道这是OP意味着什么*“...有代表链'Foo' - >'Bar'”*,对我来说似乎还不清楚? – adeneo

+0

@adeneo你说得对,这不是很清楚,所以我大都忽略了它。据我所知,它似乎不是关于原型代表团。但'Foo'(“外部”mixin)可以引用对象上已经存在的'Bar' /'Qux'(“内部”mixins)的方法。 – Bergi

+0

“一个对象'fooBar'可以调用'foo()'和'bar()'”听起来像mixin很糟糕。 – ssube

0

至于评论,不知道,但我想你可以尝试instanceof

想法是,有一个包装函数,将检查构造函数,并将调用必要的功能。替代方案可以在所有类功能中具有相同的名称功能。所以,你只需要调用object.functionName()

Sample Fiddle

function Foo() { 
 
    this.foo = function() { 
 
    console.log('foo'); 
 
    } 
 
} 
 

 
function Bar() { 
 
    this.bar = function() { 
 
    console.log('bar'); 
 
    } 
 
} 
 

 
function Qux() { 
 
    this.qux = function() { 
 
    console.log('qux'); 
 
    } 
 
} 
 

 
function createObj() { 
 
    var index = Math.floor(Math.random() * 10) % 3; 
 
    switch (index) { 
 
    case 0: return new Foo(); 
 
    case 1: return new Bar(); 
 
    case 2: return new Qux(); 
 
    } 
 
} 
 

 
function checkObjectAndCallFunc(obj) { 
 
    if (obj instanceof Foo) { 
 
    delete obj; 
 
    obj.foo(); 
 
    } else if (obj instanceof Bar) { 
 
    delete obj; 
 
    obj.bar(); 
 
    } else if (obj instanceof Qux) { 
 
    delete obj; 
 
    obj.qux(); 
 
    } 
 
} 
 

 
function test(obj) { 
 
    obj = createObj(); 
 
    checkObjectAndCallFunc(obj); 
 
    if (count < 10) initTimeout() 
 
} 
 
var count = 0; 
 
var obj = {}; 
 

 
function initTimeout() { 
 
    count++; 
 
    setTimeout(test.bind(null, obj), 1000); 
 
} 
 
initTimeout()