我正在创建一个基于 Base
类的新类,该类绑定(bind)了来自 ext
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
类内部创建新实例,它将能够使用绑定(bind)方法,而不仅仅是 Base
类方法.
所以 instance2
也会有 filter
、find
和 createNewInstance
方法。
我会使用继承相同 Base
类的不同类型的类,所以恐怕只是硬编码其中的绑定(bind)方法是行不通的 :(
这有可能实现吗?
提前致谢
最佳答案
恐怕对 javascript 的工作原理存在一些误解。我们来分析一下代码:
var ext = {
filter: function () {/*...*/},
find: function () {/*...*/}
},
FinalClass = Base.bind(ext),
所以,这里有一个绑定(bind)到 ext
的 Base
函数。这意味着,每次调用 FinalClass
时,this
都将是 ext
。
instance1 = FinalClass({name: 'John'}),
此处调用 FinalClass
并传递一个 name
等于“John”的对象。因为在 Base
中你有:
function Base(info) {
var self = this;
self.name = info.name;
// ...
return self;
}
this
是 FinalClass
中 ext
的实例,这意味着您要添加一个新属性 name
到 ext
对象。我认为你不想要那个。
然后你返回self
,这意味着你再次返回ext
。
在那之后,你有:
instance2 = instance1.createNewInstance({name: 'Mark'});
让我们看一下该方法:
self.createNewInstance = function (data) {
return new self.constructor(data);
};
因为 instance1
它不是使用 new
运算符创建的,而是 ext
本身,这意味着它的构造函数是 Object
,而不是您可能期望的 FinalClass
。
我相信您可以使用原型(prototype)继承和 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'});
希望对您有所帮助,如果您有疑问或我误解了您的问题,请告诉我!
关于javascript - 创建绑定(bind)生成的对象的新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9860999/