Crockford的deentityify方法-《The Good Parts》第41页。

4

为了自我提升,我正在阅读(并反复阅读) Señor Crockford 的《TGP》。然而,我无法理解他的 deentityify 方法的中间部分。

...
return this.replace(...,
    function (a, b) {
       var r = ...
    }
);

我理解:

  1. this.replace传递了两个参数,一个是正则表达式作为搜索值,另一个是生成替换值的函数;
  2. b用于访问实体对象中的属性;
  3. 返回的? r : a;位决定是否原样返回文本还是返回实体中相应属性的值。

我完全不明白的是a和b如何作为参数传递到function(a, b)中。是什么调用了这个函数?(我知道整个代码是自执行的,但这并没有真正澄清我的疑惑。我想问的是这个函数是如何被调用的?)

如果有人有兴趣给出类似于这个的逐行分析,我会非常感激,而且我相信其他人也会。

以下是代码:

String.method('deentityify', function ( ) {
    var entity = {
        quot: '"',
        lt: '<',
        gt: '>'
    };

    return function () {
        return this.replace(
            /&([^&;]+);/g,
            function (a, b) {
                var r = entity[b];
                return typeof r === 'string' ? r : a;
            }
        );
    };
}()); 

简而言之:replace() 函数会调用传递给它的函数。可以将其视为“回调”函数,这是一种非常典型的模式。 - Dave Newton
@DaveNewton 是的,我现在可以看到了。但我不明白的是为什么要使用 b 来检查匹配的文本是否是实体中的属性,但如果 r !== 'string'(即未找到 entity[b]),则返回 a。我本来期望的是 (1) 检查 b 是否是实体中的属性,(2a) 如果是,则替换 b 的值(即 r),否则 (2b) 将 b 放回字符串中。如果 a 是数字偏移量,为什么它会被返回作为替换值? - Nick
我手头没有这本书,所以无法帮助你。 - Dave Newton
我更新了帖子并附上了代码 - 让别人去做有点粗鲁 :) - Nick
请看我的“答案”,其实更像是一条评论。phihag 说错了,ab都不是数字偏移量。 - Dave Newton
是的,Dave,然后我错误地应用了phihag的分析,说a是数字偏移量,而他说它是b。(我知道b不是,因为他说其中一个是,所以我没有仔细看)。我开始意识到b必须缺少周围的&;才能匹配实体属性。感谢你们两个的帮助。我不太确定该选择哪个答案,因为@phihag的答案不完全正确,但它是更详细的答案。也许你可以更新一下,phihag? - Nick
2个回答

5
replace 函数可以将一个函数作为第二个参数传入。
当正则表达式匹配成功时,该函数会被调用,并根据正则表达式中的分组数来确定其签名。如果正则表达式不包含任何捕获组,则 a 为匹配到的子字符串,b 为在整个字符串中的数字偏移量。有关更多详细信息,请参阅 MDN 文档

5

a 不是数字偏移量,它是 匹配的子字符串

b (在这种情况下)是第一个分组,即匹配减去周围的 &;

该方法检查实体是否存在,并且它是一个字符串。如果是,则为其赋值替换,否则替换为原始值,减去 &;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接