К сожалению, в моем проекте мы генерируем много HTML-кода в JavaScript, например:
var html = new StringBuffer();
html.append("<td class=\"gr-my-deals\"><a href=\"").append(deal.url).append("\" target=\"_blank\">").append(deal.description).append("</a></td>");
У меня есть две конкретные жалобы по этому поводу:
Применение обоих этих предложений дает следующую эквивалентную строку кода, которую я считаю более читаемой:
var html = "<td class=’gr-my-deals’><a href=’" + deal.url + "’ target=’_blank’>" + deal.description + "</a></td>";
Сейчас я ищу способ автоматически преобразовать первую строку кода во вторую. Все, что я до сих пор придумал, - это выполнить следующую операцию поиска и замены всего нашего кода Javascript:
Find: ).append(
Replace: +
Это преобразует строку кода, показанную выше, в:
html.append("<td class=\"gr-my-deals\"><a href=\"" + deal.url + "\" target=\"_blank\">" + deal.description + "</a></td>)";
Это должно безопасно удалить все, кроме первого оператора append (). К сожалению, я не могу придумать безопасного способа автоматического преобразования экранированных двойных кавычек в одинарные. Имейте в виду, что я не могу просто выполнить поиск / замену, потому что в некоторых случаях вам действительно нужно использовать экранированные двойные кавычки. Обычно это происходит, когда вы создаете HTML, который включает вложенный JS, и этот JS содержит строковые параметры, например.
function makeLink(stringParam) {
var sb = new StringBuffer();
sb.append("<a href=\"JavaScript:myFunc('" + stringParam + "');\">");
}
Мои вопросы (наконец):
Ваше здоровье, Дон



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вот функция формата строки, которая помогает устранить конкатенацию и некрасивые значения замены.
function stringFormat( str ) {
for( i = 0; i < arguments.length; i++ ) {
var r = new RegExp( '\\{' + ( i ) + '\\}','gm' );
str = str.replace( r, arguments[ i + 1 ] );
}
return str;
}
Используйте это так:
var htmlMask = "<td class=’gr-my-deals’><a href=’{0}’ target=’_blank’>{1}</a></td>";
var x = stringFormat( htmlMask, deal.Url, deal.description );
Рассмотрите возможность перехода на Обработчик шаблонов JavaScript. Они, как правило, довольно легкие и могут значительно улучшить ясность вашего кода ... а также производительность, если у вас много повторного использования и вы выбираете тот, который предварительно компилирует шаблоны.
И чего бы это ни стоило, я бы не стал пытаться преобразовывать такой код автоматически. Какими бы уродливыми ни были существующие вещи, риск внесения мелких ошибок еще больше. Как только вы столкнетесь с ними, вручную замените вхождения более подходящим методом.
«Микро-шаблоны» Джона Ресига - очень эффективный и очень лаконичный фрагмент кода. Это также хорошо, если вы ищете способ заставить коллег делать двойную работу. Это где-то в сообщениях, которые вы связали, но я отправлю его снова: ejohn.org/blog/javascript-micro-templating
Это хорошее предложение, но не то, что в краткосрочной перспективе я просто ищу автоматический способ улучшить код (например, найти-заменить)
Как предполагает Shog9, существует несколько хороших движков для создания шаблонов JavaScript. Вот пример того, как вы могли бы использовать мой, Простые шаблоны jQuery:
var tmpl, vals, html;
tmpl = '<td class = "gr-my-deals">';
tmpl += '<a href = "#{href}">#{text}</a>';
tmpl += '</td>';
vals = {
href : 'http://example.com/example',
text : 'Click me!'
};
html = $.tmpl(tmpl, vals);
Есть веская причина, по которой вы должны использовать StringBuffer () вместо конкатенации строк в JavaScript. StringBuffer () и его метод append () используют Array и Array join () для объединения строки. Если у вас есть значительное количество частичных строк, которые вы хотите присоединить, это, как известно, более быстрый способ сделать это.
Быстрее, может быть, но я не верю, что улучшение скорости стоит затрат на ремонтопригодность.
Каждому свое - метод, о котором вы говорите, не будет поддерживать каждый разработчик. FTW, упомянутые системы шаблонов, включая подход Джона Ресига, используют Array и join ().
@ hal10001: у вас правильная производительность WRT (не то чтобы это должно иметь большое значение для отмеченных кратких примеров). Но StringBuffer.append () мучительно многословен. Использование литералов массива + join () (["<a href='", deal.url, "'target='_blank'>", deal.description, "</a>"] .join ("")) приведет к быть предпочтительнее.
Шаблоны? Создание шаблонов - отстой! Вот как я бы написал ваш код:
TD({ "class" : "gr-my-deals" },
A({ href : deal.url,
target : "_blank"},
deal.description ))
Я использую 20-строчную библиотеку под названием DOMination, которую я отправлю всем, кто попросит, для поддержки такого кода.
Преимущества многочисленны, но некоторые из наиболее очевидных:
(Ваш пример, BTW, подчеркивает единственный недостаток DOMination: любые атрибуты HTML, которые также являются зарезервированными словами JavaScript, в данном случае class, должны быть заключены в кавычки, чтобы не случилось плохого.)
Спасибо, но в идеале мне нужен способ запустить эту функцию для большого количества файлов. Если бы подобная функция была доступна в виде сценария Perl, это, вероятно, помогло бы.