2016-09-19 66 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()