Статическое членство в readonly = & gt; TypeError: XXX не является конструктором

Я предпочитаю этот подход, потому что: вам не нужно перебирать более двух коллекций, вы можете получить доступ к вещам, отличным от «имя» и «значение», если вам нужно, и вы можете дезинфицировать свои ценности, прежде чем хранить их в объект (если у вас есть значения по умолчанию, которые вы не хотите хранить, например).

$.formObject = function($o) {
    var o = {},
        real_value = function($field) {
            var val = $field.val() || "";

            // additional cleaning here, if needed

            return val;
        };

    if (typeof o != "object") {
        $o = $(o);
    }

    $(":input[name]", $o).each(function(i, field) {
        var $field = $(field),
            name = $field.attr("name"),
            value = real_value($field);

        if (o[name]) {
            if (!$.isArray(o[name])) {
                o[name] = [o[name]];
            }

            o[name].push(value);
        }

        else {
            o[name] = value;
        }
    });

    return o;
}

Использовать так:

var obj = $.formObject($("#someForm"));

Проверено только в Firefox.

1
задан midoriiro 13 July 2018 в 19:44
поделиться

1 ответ

Ошибка легче понять, если добавить консольный журнал к pointutil.ts:

import {Point} from "./point";

console.log('Point:', Point);

export class PointUtil {
    public static readonly origin: Point = new Point(12, 2);
}

Это показывает, что Point - undefined (который не является конструктором :-) Причина в том, что point.ts и pointUtil.ts импортируют друг друга и создают циклическую зависимость модуля. Это не связано с тестом, так как ошибка будет вызвана любым модулем, который импортирует point.ts.

Когда вычисляется модуль point.ts, и он запускает оценку pointUtil.ts, значение импортированного Point в pointUtil.ts будет неопределенным до тех пор, пока не будет завершена оценка модуля point.ts. Однако, поскольку определение статического свойства origin означает выполнение

PointUtil.origin = new Point(12, 2);

, это означает, что Point используется до того, как pointUtil.ts (и, следовательно, point.ts) были оценены, что привело к ошибка.

Модуль point.ts также использует импорт из pointUtil.ts, но он находится внутри метода dummyCalc, поэтому он не оценивается во время начальной оценки модуля. Это означает, что если вы импортируете pointUtil.ts перед point.ts в repl.test.ts, порядок оценки point.ts и pointUtil.ts будет отменен, и ошибка исчезнет, ​​так как point.ts не выйдет из строя на начальном undefined PointUtil.

import './pointUtil'
import {Point} from './point'

describe("REPL test", () => {
  ..
});

Это хакерское решение, поэтому лучше избегать цикла и устанавливать определения, которые сразу требуют Point в самом модуле point.ts. На самом деле, origin в любом случае более подходит как статическое свойство на Point.

1
ответ дан Oblosys 17 August 2018 в 12:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: