Чтобы понять, что происходит, нужно очень внимательно посмотреть, что на самом деле сделано.
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) {
// "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