【问题标题】:Dynamically instantiate class in javascript在javascript中动态实例化类
【发布时间】:2016-04-16 07:17:18
【问题描述】:

我查看了这个 reference link 并最终使用了 Matthew 的解决方案,因为它对我有用。

var factory ={};
factory.Tree = function(arg1,arg2,arg3,arg4){
    console.log(arg1+""+arg2+""+arg3+""+arg4); 
}
function instantiate(classname){
    return new (function(a){ return factory[classname].apply(this,a);})(Array.prototype.splice.call(arguments,1));
    // also is this ^^^ a good practice? instead of declaring the temp function beforehand
    // function t(a) {return factory[classname].apply(this,a);}
    // return new t(Array.prototype.splice.call(arguments,1));
}
var newObj = instantiate("Tree",1,2,3,4); // this prints 1234 --> works

不过,我不确定为什么使用 user123444555621 的解决方案只有在我传入“参数”(即包括“类名”在内的所有内容)时才有效:

function instantiate(classname){
    return new (Function.prototype.bind.apply(factory[classname], arguments));
}
var newObj = instantiate("Tree",1,2,3,4); // this prints 1234 --> works

但是如果我切片“arguments”并删除“classname”,然后传入结果数组,它就不会按预期工作:

function instantiate(classname){
    var args = Array.prototype.splice.call(arguments,1); 
        // ^^ I checked and this prints 1,2,3,4 as well
    return new (Function.prototype.bind.apply(factory[classname], args));
}
var newObj = instantiate("Tree",1,2,3,4); // this prints 234undefined

我不知道为什么,但不知何故,args 数组似乎(再次)被切片并删除了它的第一个元素(在本例中为 1)。

有人可以提供任何见解吗?谢谢

【问题讨论】:

    标签: javascript class


    【解决方案1】:

    你使用了正确的数组函数slice vs splice 吗?

    Array.prototype.slice() - 从现有数组的元素创建一个新数组。它不会修改原始数组。

    Array.prototype.splice() – 删除和/或插入数组中的元素。与 slice() 不同,splice() 方法修改原始数组 并返回一个新数组。 splice() 方法接受三个参数。

    【讨论】:

      【解决方案2】:

      你的问题是这一行

      var args = Array.prototype.splice.call(arguments,1); 
      

      您实际上已从arguments 中删除了第一项,同时将其转换为数组args

      只需将 1 替换为 0

      var args = Array.prototype.splice.call(arguments,0);
      

      演示

      var factory ={};
      factory.Tree = function(arg1,arg2,arg3,arg4){
          console.log(arg1+""+arg2+""+arg3+""+arg4); 
      }
      function instantiate(classname){
          var args = Array.prototype.splice.call(arguments,0); 
          return new (Function.prototype.bind.apply(factory[classname], args));
      }
      instantiate("Tree",1,2,3,4);

      【讨论】:

      • 谢谢。如果我错了,请纠正我,但我们不应该删除第一个参数并将剩余的参数作为数组返回吗?在这种情况下,删除“Tree”,并将 [1,2,3,4] 传递给 Tree 的构造函数?如果不从参数中删除任何内容,那么也许我可以直接将它传递给 apply() (只是不确定它为什么起作用)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-26
      • 2019-11-08
      • 1970-01-01
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      相关资源
      最近更新 更多