2012-03-25 62 views
1

我正在創建一個新類,它基於Base類與來自ext obj的外部方法綁定。創建一個綁定生成的obj的新實例

function Base(info) { 
    var self = this; 
    self.name = info.name; 
    self.createNewInstance = function (data) { 
     //I would like to identify the parent constructor 
     // in this case, the obj containing `filter` and `find` methods 
     // and use that to generate a new instance 
     return new self.constructor(data); 
    }; 
    return self; 
} 

var ext = { 
     filter: function() {/*...*/}, 
     find: function() {/*...*/} 
    }, 
    FinalClass = Base.bind(ext), 
    instance1 = FinalClass({name: 'John'}), 
    instance2 = instance1.createNewInstance({name: 'Mark'}); 

console.log(instance1); 
//--> {name: 'John', filter: [Function], find: [Function], createNewInstance: [Function]} 
console.log(instance2); 
//--> {name: 'Mark'} 

但你可以看到,我想從FinalClass類,這將能夠使用綁定的方法,而不是隻有Base類的人裏面創建新實例。 所以instance2也會有filter,findcreateNewInstance方法。

我會使用不同類型的繼承同樣Base類的類,所以只是硬編碼的綁定方法就不會工作,我很害怕:(

這是可能實現的?

在此先感謝

回答

2

恐怕有一些誤解有關的作品如何讓JavaScript的分析代碼:

var ext = { 
     filter: function() {/*...*/}, 
     find: function() {/*...*/} 
    }, 
    FinalClass = Base.bind(ext), 

所以,在這裏你有一個Base函數綁定到ext。這意味着,每當您撥打FinalClass時,this將是ext

instance1 = FinalClass({name: 'John'}), 

這裏你打電話FinalClass傳遞對象與name等於「約翰」。因爲在Base您有:

function Base(info) { 
    var self = this; 
    self.name = info.name; 
    // ... 
    return self; 
} 

而且thisextFinalClass的情況下,這意味着你添加新的屬性nameext對象。我認爲你不想那樣。 然後您返回self,這意味着您再次返回ext

之後,您有:

instance2 = instance1.createNewInstance({name: 'Mark'}); 

讓我們看看這個方法:

self.createNewInstance = function (data) { 
    return new self.constructor(data); 
}; 

因爲instance1它不能利用new運營商,它的ext本身而言,它意味着它的構造函數是Object,而不是你所期望的FinalClass

我相信你可以找到一個更好的方式來做你想要的原型繼承和Object.create。但是,你應該能夠獲得你正在尋找使用類似於如下代碼的結果:

function Base(info) { 
    this.name = info.name; 

    this.createNewInstance = function (data) { 
     return new this.constructor(data); 
    }; 

    return this; 
} 

var ext = { 
     filter: function() {/*...*/}, 
     find: function() {/*...*/} 
    }; 

function FinalClass(info) { 
    var object = Object.create(ext); 
    object.constructor = FinalClass; 

    return Base.call(object, info); 
} 

var instance1 = FinalClass({name: 'John'}), 
    instance2 = instance1.createNewInstance({name: 'Mark'}); 

console.log(instance1); 
console.log(instance2); 
// notice that `filter` and `find` won't probably be listed because are not "own properties", but the objects have them: 
console.log(instance1.filter); 
console.log(instance2.filter); 

你也可以在Base這概括了一下這項工作寫一個實用的方法,讓您的代碼將看起來像:

function Base(info) { 
    this.name = info.name; 

    this.createNewInstance = function (data) { 
     return new this.constructor(data); 
    }; 

    return this; 
} 

Base.create = function(extension) { 
    return function Extendend() { 
     var object = Object.create(extension); 
     object.constructor = Extendend; 

     return Base.apply(object, arguments); 
    } 
} 

var ext = { 
     filter: function() {/*...*/}, 
     find: function() {/*...*/} 
    }; 

var FinalClass = Base.create(ext); 

var instance1 = FinalClass({name: 'John'}), 
    instance2 = instance1.createNewInstance({name: 'Mark'}); 

希望它有幫助,如果你有疑問,或者我誤解了你的問題,只是讓我知道!

+0

非常感謝ZER0這正是我所期待的,謝謝你將這個偉大的答案放在一起 – zanona 2012-03-27 09:26:27

相關問題