5

我正在测试来自 JavaScrit: The Good Parts 的模块示例。我不知道函数(a,b)中谁传入了a和b。它以某种方式起作用。

Function.prototype.method = function(name, f) {
    this.prototype[name] = f;
    return this;
}
String.method('de', function() {
    var entity = {
        lt : '<',
        gt : '>'
    };
    return function() {
        return this.replace(/&([^&;]+);/g, function(a, b) {
            document.write("<br> a=" + a + " b=" + b);
            var r = entity[b];
            return typeof r === 'string' ? r : a;
        });
    };
}());
document.write("<br>" + '&lt;&gt'.de());
4

1 回答 1

1

要了解正在发生的事情,必须非常仔细地查看实际所做的事情。

Function.prototype.method = function(name, f) {
    this.prototype[name] = f;
    return this;
}

这部分很清楚,是扩展任何对象的Prototype的“捷径”。

魔法发生在代码的第二部分,之前定义的函数提供了一个自执行函数作为第二个参数!

String.method('de', function() {
    var entity = {
        lt : '<',
        gt : '>'
    };
    return function() {
        return this.replace(/&([^&;]+);/g, function(a, b) {
            // "this" will refer to the object the function is bound to.
            document.write("<br> a=" + a + " b=" + b);
            var r = entity[b];
            return typeof r === 'string' ? r : a;
        });
    };
}()); <-- The magic happens here!

这意味着,JavaScript 解释器将使用“第一个内部”函数(直接提供String.methodString.prototype.

de下面的代码做同样的事情,但在本地范围内多放了一个变量 ( )。上面的方法不会污染范围,它是一种更优雅的方式来实现这一点。您甚至可以将其进一步展开并放入entity本地范围。

var de = function() {
    var entity = {
        lt : '<',
        gt : '>'
    };
    return function() {
        return this.replace(/&([^&;]+);/g, function(a, b) {
            // "this" will refer to the object the function is bound to.
            document.write("<br> a=" + a + " b=" + b);
            var r = entity[b];
            return typeof r === 'string' ? r : a;
        });
    };
};
String.method('de', de());

现在回答您关于如何发挥作用a的问题!这与传递的第二个参数是函数时的行为b方式有关。String.replace评论中提供的链接DCoder 很好地解释了这一点!该参数a是整个匹配的子字符串,b是第一个匹配的“带括号的子匹配”。

于 2012-10-27T08:42:44.253 回答