gpt4 book ai didi

javascript - javascript中的动态对象构造?

转载 作者:行者123 更新时间:2023-12-03 13:20:35 27 4
gpt4 key购买 nike

当我想使用从其他地方提供的参数调用 javascript 中的函数时,我可以使用 apply函数的方法如:

array = ["arg1", 5, "arg3"] 
...
someFunc.apply(null, array);
但是如果我需要以类似的方式调用构造函数怎么办?这似乎不起作用:
array = ["arg1", 5, "arg3"] 
...
someConstructor.apply({}, array);
至少不像我尝试的那样:
template = ['string1', string2, 'etc'];
var resultTpl = Ext.XTemplate.apply({}, template);
这不起作用:
Ext.XTemplate.prototype.constructor.apply({}, template);
有什么办法可以使那个工作吗? (在这种特殊情况下,我发现 new Ext.XTemplate(template) 会起作用,但我对一般情况感兴趣)
类似的问题,但特定于内置类型并且没有我可以使用的答案:
Instantiating a JavaScript object by calling prototype.constructor.apply
谢谢你。
编辑:
时间已经过去了,ES6 和转译器现在已经成为一件事。
在 ES6 中,做我想做的事是微不足道的: new someConstructor(...array) .
Babel会把它变成 ES5 new (Function.prototype.bind.apply(someConstructor, [null].concat(array)))();这在 How to construct JavaScript object (using 'apply')? 中有解释.

最佳答案

没有简单直接的方法可以使用构造函数来做到这一点。这是因为当您使用 new 时会发生特殊情况。关键字来调用构造函数,所以如果你不打算这样做,你必须模拟所有这些特殊的东西。他们是:

  • 创建一个新的对象实例(您正在这样做)。
  • 将该对象的内部原型(prototype)设置为构造函数的prototype属性(property)。
  • 设置该对象的 constructor属性(property)。
  • 使用该对象实例调用构造函数作为 this值(value)(你正在这样做)。
  • 处理来自构造函数的特殊返回值。

  • 我想就是这样,但值得仔细检查 the spec .

    因此,如果您可以避免它并直接使用构造函数,我会这样做。 :-) 但是,如果您不能,您仍然可以这样做,这很尴尬并且涉及变通方法。 (另请参阅 StackOverflow 上的 this related answer,尽管我在这里涵盖了所有内容 [然后还介绍了一些内容。)

    您最大的问题是上面的#2:设置对象的内部原型(prototype)。长期以来,没有标准的方法来做到这一点。一些浏览器支持 __proto__属性,所以如果它在那里,你可以使用它。好消息是 ECMAScript 5 引入了一种明确执行此操作的方法: Object.create .因此,像 Chrome 这样的尖端浏览器将拥有它。但是,如果您使用的浏览器既没有 Object.create也不是 __proto__ ,它变得有点难看:

    1)定义自定义构造函数。

    2) 设置其 prototype prototype 的属性(property)真实构造函数的属性

    3)用它来创建一个空白对象实例。

    它为您处理原型(prototype)。然后你继续:

    4) 替换 constructor该实例的属性与真正的构造函数。

    5) 通过 apply调用真正的构造函数.

    6)如果真正的构造函数的返回值是一个对象,用它代替你创建的那个;否则,请使用您创建的那个。

    像这样( live example):
    function applyConstruct(ctor, params) {
    var obj, newobj;

    // Use a fake constructor function with the target constructor's
    // `prototype` property to create the object with the right prototype
    function fakeCtor() {
    }
    fakeCtor.prototype = ctor.prototype;
    obj = new fakeCtor();

    // Set the object's `constructor`
    obj.constructor = ctor;

    // Call the constructor function
    newobj = ctor.apply(obj, params);

    // Use the returned object if there is one.
    // Note that we handle the funky edge case of the `Function` constructor,
    // thanks to Mike's comment below. Double-checked the spec, that should be
    // the lot.
    if (newobj !== null
    && (typeof newobj === "object" || typeof newobj === "function")
    ) {
    obj = newobj;
    }

    // Done
    return obj;
    }

    您可以更进一步,仅在必要时使用假构造函数,查看是否 Object.create__proto__首先支持,像这样( live example ):
    function applyConstruct(ctor, params) {
    var obj, newobj;

    // Create the object with the desired prototype
    if (typeof Object.create === "function") {
    // ECMAScript 5
    obj = Object.create(ctor.prototype);
    }
    else if ({}.__proto__) {
    // Non-standard __proto__, supported by some browsers
    obj = {};
    obj.__proto__ = ctor.prototype;
    if (obj.__proto__ !== ctor.prototype) {
    // Setting it didn't work
    obj = makeObjectWithFakeCtor();
    }
    }
    else {
    // Fallback
    obj = makeObjectWithFakeCtor();
    }

    // Set the object's constructor
    obj.constructor = ctor;

    // Apply the constructor function
    newobj = ctor.apply(obj, params);

    // If a constructor function returns an object, that
    // becomes the return value of `new`, so we handle
    // that here.
    if (typeof newobj === "object") {
    obj = newobj;
    }

    // Done!
    return obj;

    // Subroutine for building objects with specific prototypes
    function makeObjectWithFakeCtor() {
    function fakeCtor() {
    }
    fakeCtor.prototype = ctor.prototype;
    return new fakeCtor();
    }
    }

    在 Chrome 6 上,以上使用 Object.create ;在 Firefox 3.6 和 Opera 上,它使用 __proto__ .在 IE8 上,它使用了假构造函数。

    以上是相当即兴的,但它主要处理我在这方面所知道的问题。

    关于javascript - javascript中的动态对象构造?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3871731/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com