【问题标题】:Dynamic instantiation in JavaScriptJavaScript 中的动态实例化
【发布时间】:2011-02-17 13:07:54
【问题描述】:

除了eval(`o = new ${className}(${args.join(", ")})`),还有其他方法可以使用可变参数列表来实例化对象吗?

例如:var foo = instantiate(className, [arg1, arg2, ...])

【问题讨论】:

    标签: javascript


    【解决方案1】:

    你可以用这样的变量参数列表实例化一个对象:

    function instantiate(className, args) {
        var o, f, c;
        c = window[className]; // get reference to class constructor function
        f = function(){}; // dummy function
        f.prototype = c.prototype; // reference same prototype
        o = new f(); // instantiate dummy function to copy prototype properties
        c.apply(o, args); // call class constructor, supplying new object as context
        o.constructor = c; // assign correct constructor (not f)
        return o;
    }
    

    旁注:您可能希望传递对类构造函数的直接引用:

    var foo = instantiate(Array, [arg1, arg2, ...]);
    // Instead of:
    var foo = instantiate("Array", [arg1, arg2, ...]);
    

    ...这使得它与非全局函数兼容。

    【讨论】:

    • window[className] 对我来说是未定义的(是的,三次检查我的班级名称)。
    • TypeError: c is undefined because (window[className] is undefined )
    • 而不是c.apply(o, args),我觉得应该是c.constructor.apply(o, args)。其他错误发生为“必须使用 'new' 运算符调用类构造函数。”。
    【解决方案2】:

    在 ES5 中使用 Object.create()

    function instantiate(constructor, args) {
        var instance = Object.create(constructor.prototype);
        constructor.apply(instance, args);
        return instance;
    }
    

    在 ES6 中使用 spread operator

    var foo = new constructor(...args);
    

    【讨论】:

    • 某事告诉我这将比接受的答案快四倍。
    • @inetphantom 是第一个还是第二个?
    • 第二个。它只是:一个不知道传播运算符的人不会明白你的意思。
    • @inetphantom 是的,我明白它是如何令人困惑的,但我想不出比文档链接更好的方法了。这是一个代码示例:jsfiddle.net/upru8scm
    • 投了反对票,因为这个答案需要使用类型文字,这与问题的前提相反。
    【解决方案3】:

    好吧,您总是可以按照以下方式进行操作。添加到 Dino 原型的任何内容都可以在实例化对象之间共享。与普通构造函数模式的不同之处在于,实例化对象不必具有完全相同的私有属性集。可以为它们中的每一个动态设置它们。

    function Dino(a,b){
      for(i = 0; i< a.length; i++) this[a[i]] = b[i];
    }
    
    var props = ["foo", "bar"],
       values = [42, 37],
          obj = new Dino(props,values);
    console.log(obj);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-26
      • 2019-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多