2012-10-27 7 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; 
} 

Эта часть довольно понятна, это «ярлык», расширяющий прототип любого объекта.

Магия происходит во второй части вашего кода, ранее определенная функция снабжается функцией самоисполнения в качестве второго параметра!

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 - это первая совпадающая «скобка в скобках».

+0

Да, это отличный ответ. Большое спасибо! –

+0

@JAny Спасибо, не могли бы вы принять это как ответ? (Нажмите зеленую галочку ниже оценки ответа, чтобы сделать это.) Также хороший вопрос занял некоторое время, чтобы понять, что происходит. – clentfort

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

  • Нет связанных вопросов^_^