2012-03-25 24 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

相关问题