2012-10-27 57 views
5

我正在测试JavaScrit的模块示例:The Good Parts。我不知道谁通过a和b的功能(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

[String.replace'的文档](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter)应该可以回答这个问题。 – DCoder

+0

这些是lt和gt? – Darek

+0

容易理解,如果你快速发现自执行函数会发生什么,否则它会花费你几分钟的时间想知道为什么'String.de'不会打印返回函数的代码。 – clentfort

回答

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.method)作为实际功能,由于“第一内”功能分配给它之前执行到String.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()); 

现在,你的问题就如何ab开始发挥作用! 这与String.replace在传递的第二个参数是一个函数时的行为有关。注释中提供的link DCoder解释了这非常好!参数a是整个匹配的子字符串,b是第一个匹配的“加括号的子匹配”。

+0

是的,这是一个很好的答案。非常感谢你! –

+0

@JAny谢谢,你介意接受这个答案吗? (点击答案分数下面的绿色选中标记。)另外一个很好的问题,花了我一些时间来弄清楚发生了什么。 – clentfort

相关问题