Передача аргументов в расширение string.prototype в javascript

#javascript #string #prototype

#javascript #строка #прототип

Вопрос:

Я использую string.prototype для связывания текстовых фрагментов на моем веб-сайте. На некоторых сайтах я хочу добавлять разные заметки и, следовательно, хочу передать дополнительный аргумент linkify.

Моя первоначальная идея заключалась в том, чтобы сделать это следующим образом.

 function linkifyText() {
    
    var uglyLinksPattern = /[(.*?)]/gim; // match all letters between square brackets
                
    if(!String.linkify) {
        String.prototype.linkify = function(note) {
            var textInput = this;    
            return textInput.replace(uglyLinksPattern, '<a target="_blank" rel="noopener nofollow" href="$amp;">$amp;</a>'   note);            
        }
    }
    return uglyLinksPattern
}
        
function linkifyDialogue (text) {    
    linkifyText();
    var note = 'Ad';        
    var linkedText = String.linkify.call(text, note);
    $('#textElem').html(linkedText);        
}
  

Я нашел несколько руководств, использующих call и apply . Однако я не смог перенести его в свой случай и надеюсь получить ответ о том, как передать аргумент свойству string.prototype . Так в чем же хитрость?

Комментарии:

1. Вы хотите определить String.linkify (статический метод) или String.prototype.linkify ?

2. String.prototype.linkify

3. Тогда вы тестируете неправильную вещь if .

4. Не уверен, почему вы фиксируете var textInput = this , когда вы могли бы просто использовать this.replace вместо этого. Также, учитывая, что сейчас 2020 год, почему бы и нет const uglyLinksPattern ? Попробуйте использовать let и const вместо var .

5. Хорошо, в этом есть смысл. textInput было для лучшей читаемости.

Ответ №1:

Способ, которым вы пытались это реализовать, довольно странный (без обид). Вы могли бы сделать это намного проще. См .:

 //Do this just once
String.prototype.linkify=function(note) {
    return this.replace(/[(.*?)]/gim,"<a target='_blank' rel='noopener nofollow' href='$1'>$1</a>" note);
};

function linkifyDialogue(text) {    
    var note="Ad",        
        linkedText=text.linkify(note);
    $('#textElem').html(linkedText);        
}
  

Все строки уже являются объектами. Если вы добавляете метод в прототип, нет необходимости использовать call() or apply() , если вам это действительно не нужно (т. Е. Вызывать его с другим значением для this , Передавать массив значений в качестве разных параметров и т. Д.).

Комментарии:

1. спасибо. так что это очень простая форма всей функции. В нем есть адрес электронной почты, псевдо-шаблоны, шаблоны markdown и т. Д. Некоторые из них экранировали текст, некоторые нет… Прототип строки определяется в конструкторе и должен вызываться в разных экземплярах… Итак, он вырос вот так и выглядит немного раздутым в моей публикации. Однако, если я хочу вызвать string.prototype в linkify внутри другой функции, как я могу передать в нее переменную?

2. Вы определяете с prototype помощью, вы не вызываете с ним.

3. Существует только один string prototype . Каждое внесенное вами изменение немедленно становится доступным во всем окне. Поэтому, если вы захотите вызвать его откуда-то еще, он будет доступен. И не имело бы смысла переопределять linkify в разных частях вашего кода. Если вам нужно, чтобы он имел различное поведение в зависимости от контекста, вы можете: а) добавить другой параметр, чтобы указать ему, что делать ( String.prototype.linkify=function(note,somethingElse,whatever) ) , или б) вообще не использовать String.prototype и создать класс, содержащий все различные методы обработки текста.