解释 Sizzle(CSS 选择器引擎)中的一段疯狂的 JS 代码

发布于 2024-08-26 23:20:11 字数 899 浏览 7 评论 0原文

所以,这里是预过滤“CHILD”的函数:

function(match){
    if ( match[1] === "nth" ) {
        // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
        var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
            match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
            !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);

        // calculate the numbers (first)n+(last) including if they are negative
        match[2] = (test[1] + (test[2] || 1)) - 0;
        match[3] = test[3] - 0;
    }

    // TODO: Move to normal caching system
    match[0] = done++;

    return match;
}

代码摘自 sizzle.js 的第 442-458 行

那么,为什么 var test = ... 行让 exec 输入布尔值呢?或者这真的是一个字符串吗?

有人可以通过将其分成几行代码来解释它吗?

So, here is the function for pre-filtering "CHILD":

function(match){
    if ( match[1] === "nth" ) {
        // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
        var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
            match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
            !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);

        // calculate the numbers (first)n+(last) including if they are negative
        match[2] = (test[1] + (test[2] || 1)) - 0;
        match[3] = test[3] - 0;
    }

    // TODO: Move to normal caching system
    match[0] = done++;

    return match;
}

The code is extracted from line 442-458 of sizzle.js.

So, why is the line var test = ..., have the exec inputing a boolean? Or is that really a string?

Can someone explain it by splitting it into a few more lines of code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沉溺在你眼里的海 2024-09-02 23:20:11

exec 方法将接收一个字符串,因为 布尔逻辑运算符可以返回操作数,但不一定是布尔结果,例如:

逻辑AND运算符(&& ),如果第一个操作数为真,则返回第二个操作数的值:如果为真,

true && "foo"; // "foo"

则返回第一个操作数的值本身falsy

NaN && "anything"; // NaN
0 && "anything";   // 0

如果第一个操作数是逻辑或运算符(||),则将返回第二个操作数的值 falsy

false || "bar"; // "bar"

如果第一个操作数本身是非 falsy,它将返回第一个操作数的值:

"foo" || "anything"; // "foo"

Falsy 值为: nullundefinedNaN0、零长度字符串,当然还有 false.

在布尔上下文中评估的任何其他内容都是truthy(将强制为true)。

那么,让我们看看这个表达式:

var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
  match[2] === "even" && "2n" ||  // return '2n' if match[2] is 'even'
  match[2] === "odd" && "2n+1" || // return '2n+1' if it's 'odd'
  !/\D/.test(match[2]) && "0n+" + match[2]|| // return '0n+N' if it's a digit(N) 
  match[2]  // otherwise, return the match[2] value
 );

The exec method will receive a string, because the Boolean Logical Operators can return an operand, and not necessarily a Boolean result, for example:

The Logical AND operator (&&), will return the value of the second operand if the first is truthy:

true && "foo"; // "foo"

And it will return the value of the first operand if it is by itself falsy:

NaN && "anything"; // NaN
0 && "anything";   // 0

The Logical OR operator (||) will return the value of the second operand, if the first one is falsy:

false || "bar"; // "bar"

And it will return the value of the first operand if it is by itself non-falsy:

"foo" || "anything"; // "foo"

Falsy values are: null, undefined, NaN, 0, zero-length string, and of course false.

Anything else, evaluated in boolean context is truthy (will coerce to true).

So, let's look the expression:

var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
  match[2] === "even" && "2n" ||  // return '2n' if match[2] is 'even'
  match[2] === "odd" && "2n+1" || // return '2n+1' if it's 'odd'
  !/\D/.test(match[2]) && "0n+" + match[2]|| // return '0n+N' if it's a digit(N) 
  match[2]  // otherwise, return the match[2] value
 );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文