Javascript,实现自定义Object.Create

时间:2014-11-29 16:58:05

标签: javascript tree prototype

我需要在JavaScript中实现继承树,其中每个节点可以有多个父节点。我们必须自己实施Object.CreateObject.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,而是返回其他内容(以某种方式创建自己的实例)。

2 个答案:

答案 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);