3

我在搞乱 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
});

因此,有人可以指出我为什么第一次测试失败的正确方向吗?

4

1 回答 1

3

简短回答source正则表达式文字/(?:)/和您从中获得的对象的属性值不同new RegExp()。在文字的情况下它是/(?:)/,而在对象的情况下,它是一个空字符串。当您执行/ /andnew 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
于 2011-04-18T20:05:30.470 回答