爲了理解發生了什麼,人們必須非常仔細地看看實際做了什麼。
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());
現在,你的問題就如何a
和b
開始發揮作用! 這與String.replace
在傳遞的第二個參數是一個函數時的行爲有關。註釋中提供的link DCoder解釋了這非常好!參數a
是整個匹配的子字符串,b
是第一個匹配的「加括號的子匹配」。
[String.replace'的文檔](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter)應該可以回答這個問題。 – DCoder
這些是lt和gt? – Darek
容易理解,如果你快速發現自執行函數會發生什麼,否則它會花費你幾分鐘的時間想知道爲什麼'String.de'不會打印返回函數的代碼。 – clentfort