2016-09-19 33 views
8

Giả sử tôi có hàm hàm dựng Foo, BarQux. Làm thế nào tôi có thể tạo một đối tượng mới với một chuỗi đại biểu (sử dụng các nhà xây dựng) mà tôi sẽ tự động chọn khi đang bay?Thừa kế thừa kế động

Ví dụ: đối tượng sẽ có chuỗi ủy quyền Foo ->Bar.
Một đối tượng khác sẽ có chuỗi 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'); 
    } 
} 

Một đối tượng fooBar sẽ có thể gọi foo()bar(). Một đối tượng khác fooQux sẽ có thể gọi foo()qux(). Vv

+0

+ cho rằng phái đoàn thay vì thừa kế. Bạn cũng nên cư trú nguyên mẫu của nhà xây dựng tôi giả sử. – Redu

+3

Xin lỗi một chút nhầm lẫn. Bạn muốn làm gì? – Neal

+0

Khi nào bạn muốn thiết lập liên kết chuỗi? Khi tạo một cá thể mới bằng cách sử dụng hàm tạo? Làm thế nào một đối tượng 'fooBar' được tạo ra? – nils

Trả lời

6

Bạn có thể sử dụng những nhà xây dựng như mixins:

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

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

Nhưng bạn có thể muốn viết chúng như trang trí, thậm chí có thể trở về đối tượng điều chỉnh, không phải là nhà thầu, bởi vì bạn không thể sử dụng nguyên mẫu của họ anyway. Vì vậy, một mô hình thuận tiện hơn sẽ

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; 
} 

để bạn có thể sử dụng chúng như

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

Điều đó sẽ cho phép bạn thực hiện 'fooBar.bar()', không chắc đó có phải là ý nghĩa của OP hay không * "... có chuỗi ủy nhiệm' Foo' -> 'Bar'" *, có vẻ không rõ ràng đối với tôi không? – adeneo

+0

@adeneo Bạn nói đúng, nó không hoàn toàn rõ ràng, vì vậy tôi hầu như bỏ qua nó. Nó không có vẻ là về đoàn mẫu thử nghiệm như xa như tôi có thể nói. Nhưng 'Foo' (mixin" bên ngoài ") có thể tham chiếu đến các phương thức' Bar'/'Qux' (các mixin" bên trong ") đã tồn tại trên đối tượng. – Bergi

+0

"Một đối tượng' fooBar' sẽ có thể gọi là 'foo()' và 'bar()' "có vẻ rất khủng khiếp giống như mixin. – ssube

0

Như nhận xét, không chắc chắn nhưng tôi đoán bạn có thể thử instanceof.

Ý tưởng là, có hàm bao bọc sẽ kiểm tra hàm tạo và sẽ gọi hàm cần thiết. Một sự thay thế có thể có cùng chức năng tên trong tất cả các hàm lớp. Vì vậy, bạn chỉ cần gọi 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()