我需要在JavaScript中实现继承树,其中每个节点可以有多个父节点。我们必须自己实施Object.Create
和Object.call
方法。我们特别不允许使用new
关键字。以下是我到目前为止的情况:
var myObject = {
hash:0,
parents: [],
create: function(args){
//TODO check if not circular
if(args instanceof Array){
for(i=0;i<args.length;i++){
this.parents.push(args[i]);
}
}
return this;
},
call : function(fun,args){
//TODO: dfs through parents
return this[fun].apply(this,args);
},
}
var obj0 = myObject.create(null);
obj0.func = function(arg) { return "func0: " + arg; };
var obj1 = myObject.create([obj0]);
var obj2 = myObject.create([]);
obj2.func = function(arg) { return "func2: " + arg; };
var obj3 = myObject.create([obj1, obj2]);
var result = obj0.call("func", ["hello"]);
alert(result);
//calls the function of obj2 istead of obj0
这段代码的问题在于我调用了obj2的函数而不是obj0&#39; s。我怀疑create()
函数不应该返回this
,而是返回其他内容(以某种方式创建自己的实例)。
答案 0 :(得分:2)
在当前的解决方案中,您实际上并没有使用myObject.create()
函数创建新对象,而只是使用相同的现有对象并重置其父数组。然后,当您定义.func()
时,您将覆盖该值,这就是警报中出现func2:
的原因。
您需要做的是返回一个全新的对象。在this
中返回myObject.create()
只会返回现有对象,这就是事情被覆盖的原因。
为避免使用new关键字,您需要执行功能继承或原型继承。以下解决方案是功能继承:
function myObject (possibleParents) {
//create a new node
var node = {};
//set it's parents
node.parents = [];
//populate it's parents if passed in
if (possibleParents) {
if (possibleParents instanceof Array) {
for (var index = 0; index < possibleParents.length; index++) {
node.parents.push(possibleParents[index]);
}
} else {
node.parents.push(possibleParents);
};
}
//
node.call = function(fun,args) {
return this[fun].apply(this,args);
};
return node;
};
var obj0 = myObject();
obj0.func = function(arg) { return "func0: " + arg; };
var obj1 = myObject([obj0]);
var obj2 = myObject();
obj2.func = function(arg) { return "func2: " + arg; };
var obj3 = myObject([obj1, obj2]);
var result = obj0.call("func", ["hello"]);
alert(result); // this will successfully call "func0: " + arg since you created a new object
答案 1 :(得分:0)
我只是通过使用函数而不是变量来解决这个问题。
function myObject () {
this.parents = [];
this.setParents = function(parents){
if(parents instanceof Array){
for(i=0;i<parents.length;i++){
this.parents.push(parents[i]);
}
}
};
this.call = function(fun,args) {
return this[fun].apply(this,args);
};
}
var obj0 = new myObject();
obj0.func = function(arg) { return "func0: " + arg; };
var obj2 = new myObject();
obj2.func = function(arg) { return "func2: " + arg; };
var result = obj0.call("func", ["hello"]);
alert(result);