2015-08-11 2 views
1

Я пытаюсь обмотать мозг вокруг замыканий. Я читал Javascript: хорошие части, и автор представляет этот фрагмент кода для добавления «» deentityify метод объектов String, идея в том, чтобы расшифровать HTML-enocoded символы:Javascript: Какие параметры передаются функции?

// the method method: 
Function.prototype.method = function(name, func) { 
     if (! this.prototype[name]) { 
       this.prototype[name] = func; 
       return this; 
     } 
} 

String.method('deentityify', function() { 

     // entity table: maps entity names 
     // to characters: 
     var entity = { 
       quot: '"', 
       lt: '<', 
       gt: '>', 
     }; 

     // Return the deentityify method: 
     return function() { 
       return this.replace(/&([^&;]+);/g, 
         // What are a & b, how are they getting passed?! 
         function (a, b) { 
           // console.log added by me, unsuccessfully: 
           console.log('a = ' + a); 
           console.log('b = ' + b); 
           var r = entity[b]; 
           return typeof r === 'string' ? r : a; 
         } 
       ); 
     }; 
}()); 

Так я понимаю большинство о том, что здесь происходит, кроме фактических параметров, передаваемых функции, определяемой как второй параметр String.replace. Как определить «a» и «b»?

Непосредственно вызов '"' .deentityify() явно не передает никаких параметров. Итак, как они определяются? В качестве второстепенного вопроса, почему console.log() не работает для регистрации значений a и b? Могу ли я успешно записывать такие переменные?

Спасибо за помощь.

EDIT: 'not' ранее отсутствовал в последнем предложении, что делает смысл неясным.

+0

Попробуйте '' { ".deentityify()' - функция только делает что-нибудь интересное, когда вы используете ее в строке с объектами HTML в ней. – Pointy

ответ

1

Функцию .replace() можно вызвать с помощью функции в качестве второго параметра. Когда вы это делаете, функция вызывается после того, как регулярное выражение успешно совпадает с параметрами, извлеченными из процесса сопоставления.

Первым параметром всегда является вся согласованная часть исходной строки. Последующие параметры представляют собой «группы захвата» из регулярного выражения.

В этом случае регулярное выражение равно /&([^&;]+);/g. Это соответствует амперсанду, за которым следует любое количество символов, отличных от амперсанда или точки с запятой, за которым следует точка с запятой. Символы между ведущими амперсандами и конечной точкой с запятой «захватываются», потому что эта часть регулярного выражения заключена в скобки.

Таким образом, если строка источника

Hello &mdash; world! 

затем соответствие против этого регулярного выражения (один раз) даст:

  • &mdash; в качестве общей найденной строки
  • mdash в качестве значения первая (и только в этом случае) захваченная группа.

Таким образом:

"Hello &mdash; world!".replace(/&([^&;]+);/g, function(all, group) { 
    alert("entire match: " + all + " group: " + group); 
}); 

покажет сообщение в соответствии с тем, что я перечислил выше.

Теперь, помимо всего прочего, код в вопросе включает еще один слой интересного поведения. Функция фактически передана функции method() не такая большая внешняя функция, но функция от этого. Эта возвращаемая функция ожидает, что ее вызывают так, что this является экземпляром String; в противном случае вызов this.replace() не будет работать.

+0

Большое вам спасибо! Теперь это имеет гораздо больше смысла! На странице w3schools не упоминался синтаксис второго параметра как функции. Я все еще не получаю, хотя я не могу использовать console.log() для любой из этих переменных. Есть ли какая-то особая причина, которая не работает? – rumdrums

+0

@rumdrums хорошо, вы только попадете в эту функцию, если регулярное выражение что-то соответствует. Попробуйте со строкой, подобной '' Hi там '' - вы должны увидеть '# 32' как значение' b'. – Pointy

+0

Вы правы - еще раз спасибо за полезный ответ. – rumdrums

Смежные вопросы