Создание объекта JavaScript путем вызова prototype.constructor.apply - PullRequest
53 голосов
/ 08 октября 2008

Позвольте мне начать с конкретного примера того, что я пытаюсь сделать.

У меня есть массив компонентов год, месяц, день, час, минута, секунда и миллисекунды в виде [ 2008, 10, 8, 00, 16, 34, 254 ]. Я хотел бы создать экземпляр объекта Date, используя следующий стандартный конструктор:

new Date(year, month, date [, hour, minute, second, millisecond ])

Как я могу передать свой массив этому конструктору, чтобы получить новый экземпляр Date? [ Обновление : Мой вопрос действительно выходит за рамки этого конкретного примера. Мне бы хотелось общее решение для встроенных классов JavaScript, таких как Date, Array, RegExp и т. Д., Конструкторы которых мне недоступны. ]

Я пытаюсь сделать что-то вроде следующего:

var comps = [ 2008, 10, 8, 00, 16, 34, 254 ];
var d = Date.prototype.constructor.apply(this, comps);

Мне, наверное, нужно где-то там "new". Вышеуказанное просто возвращает текущее время, как если бы я позвонил "(new Date()).toString()". Я также признаю, что могу быть совершенно не в том направлении с вышесказанным:)

Примечание : Нет eval() и нет доступа к элементам массива один за другим, пожалуйста. Я почти уверен, что смогу использовать массив как есть.


Обновление: дальнейшие эксперименты

Так как никто еще не смог придумать рабочий ответ, я сделал больше, играя вокруг. Вот новое открытие.

Я могу сделать это с моим собственным классом:

function Foo(a, b) {
    this.a = a;
    this.b = b;

    this.toString = function () {
        return this.a + this.b;
    };
}

var foo = new Foo(1, 2);
Foo.prototype.constructor.apply(foo, [4, 8]);
document.write(foo); // Returns 12 -- yay!

Но он не работает с внутренним классом Date:

var d = new Date();
Date.prototype.constructor.call(d, 1000);
document.write(d); // Still returns current time :(

Также не работает с номером:

var n = new Number(42);
Number.prototype.constructor.call(n, 666);
document.write(n); // Returns 42

Может быть, это просто невозможно с внутренними объектами? Я тестирую с Firefox BTW.

Ответы [ 13 ]

0 голосов
/ 17 февраля 2010

Вы можете сделать это с вопиющим, вопиющим злоупотреблением eval:

var newwrapper = function (constr, args) {
  var argHolder = {"c": constr};
  for (var i=0; i < args.length; i++) {
    argHolder["$" + i] = args[i];
  }

  var newStr = "new (argHolder['c'])(";
  for (var i=0; i < args.length; i++) {
    newStr += "argHolder['$" + i + "']";
    if (i != args.length - 1) newStr += ", ";
  }
  newStr += ");";

  return eval(newStr);
}

пример использования:

function Point(x,y) {
    this.x = x;
    this.y = y;
}
var p = __new(Point, [10, 20]);
alert(p.x); //10
alert(p instanceof Point); //true

наслаждайся =).

0 голосов
/ 09 октября 2008
var comps = [ 2008, 10, 8, 00, 16, 34, 254 ];
var d = eval("new Date(" + comps.join(",") + ");");
0 голосов
/ 08 октября 2008

1001 * Отредактировано *

Извините, я был уверен, что сделал это так много лет назад, сейчас я буду придерживаться:

var d = new Date (comps [0], comp [1], comp [2], comp [3], comp [4], comp [5], comp [6]);

Edit:

Но помните, что объект Date в javascript использует индексы в течение нескольких месяцев, поэтому приведенный выше массив означает

8 ноября 2008 г. 00: 16: 34: 254

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...