2012-10-27 88 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

相關問題