Почему этот тест QUnit RegExp не работает?

Я возился с QUnit и наткнулся на одну вещь.

Я попробовал этот простой тест в Chrome:

deepEqual(new RegExp(), /(?:)/);

Я предполагал, что это пройдет, так как new RegExp() возвращает /(?:)/ в консоли разработчика. Кажется невозможным «просто» выполнить new RegExp() === /(?:)/ за RegExps, но функции toString() возвращают одно и то же и равны.

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

deepEqual(new RegExp(" "), / /);

Итак, из следующих тестов первый не проходит:

test("test", function() {
    deepEqual(new RegExp(), /(?:)/); // fail
    deepEqual(new RegExp(" "), / /); // pass
    equal(new RegExp().toString(), /(?:)/.toString()); // pass
});

Поэтому, может ли кто-нибудь указать мне правильное направление, почему первый тест не работает?


person pimvdb    schedule 18.04.2011    source источник


Ответы (1)


Короткий ответ: значение свойства source отличается для литерала регулярного выражения /(?:)/ и объекта, который вы получаете от new RegExp(). В случае литерала это /(?:)/, тогда как в случае объекта это пустая строка. Когда вы делаете / / и new RegExp(" "), значение свойства source одинаково (оба являются строками с одним пробелом).

Длинный ответ: если вы посмотрите исходный код Qunit, вы увидите этот фрагмент кода:

"regexp": function (b, a) {
    return QUnit.objectType(b) === "regexp" &&
        a.source === b.source && // the regex itself
        a.global === b.global && // and its modifers (gmi) ...
        a.ignoreCase === b.ignoreCase &&
        a.multiline === b.multiline;
};

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

function eq(x, y) {
   console.log("x.source:", "'" + x.source + "'", "y.source:", "'" + y.source + "'", "===:", x.source === y.source);
   console.log("x.global:", x.global, "y.global:", y.global, "===:", x.global === y.global);
   console.log("x.ignoreCase:", x.ignoreCase, "y.ignoreCase:", y.ignoreCase, "===:", x.ignoreCase === y.ignoreCase);
   console.log("x.multiline:", x.multiline, "y.multiline:", y.multiline, "===:", x.multiline === y.multiline);
}

Когда вы вызываете это с помощью eq(/(?:)/, new RegExp());, вы получаете:

x.source: '(?:)' y.source: '' ===: false
x.global: false y.global: false ===: true
x.ignoreCase: false y.ignoreCase: false ===: true
x.multiline: false y.multiline: false ===: true

Принимая во внимание, что когда вы вызываете его с помощью eq(/ /, new RegExp(" "));, вы получаете:

x.source: ' ' y.source: ' ' ===: true
x.global: false y.global: false ===: true
x.ignoreCase: false y.ignoreCase: false ===: true
x.multiline: false y.multiline: false ===: true
person Vivin Paliath    schedule 18.04.2011