Using a loop to generate strings is common in real-world development. A function for generating HTML lists is a good example. It takes a collection of elements as an input and returns an HTML list of them:
const coll = ['milk', 'butter'];
buildHTMLList(coll);
// <ul><li>milk</li><li>butter</li></ul>
This problem can, of course, be solved by brute force:
- 1. Create a variable called
result
with the value<ul>
. - Loop through the elements in the collection and add another
<li>
element to the result each time. - 3. Add
</ul>
at the end and returnresult
at the end of the function.
const buildHTMLList = (coll) => {
let result = '<ul>';
for (const item of coll) {
result = `${result}<li>${item}</li>`;
// or: result += `<li>${item}</li>`;
}
result = `${result}</ul>`;
return result;
}
This method works, but for most programming languages it's really inefficient. The point is that concatenation and interpolation both generate a new string instead of using the old one, and this situation is repeated with each iteration, and the string gets bigger and bigger. Copying strings wastes a lot of memory and can affect performance. Of course, for most applications, this problem is irrelevant because of the small amount of data being processed, but the more efficient approach is no less difficult to implement and has several advantages. Therefore, it's worthwhile getting used to doing it the best way now.
The correct way, in the case of dynamic languages, is to form an array, which you can then turn into a string using the join()
method:
const buildHTMLList = (coll) => {
const parts = [];
for (const item of coll) {
parts.push(`<li>${item}</li>`);
}
// The join method combines array elements into a string
// The first argument is used as
// a separator between values
const innerValue = parts.join('');
const result = `<ul>${innerValue}</ul>`;
return result;
}
The code size remains almost unchanged, but the way the result is generated is different. Instead of a string, first an array is collected, which is then converted to a string using the join() method. In addition to efficiency, this approach has a few additional advantages:
- This code is easier to debug. Data represented by an array is easier to isolate visually and programmatically
- An array is a structure, which means it can be modified further. There's not much you can do with a ready-made string
By adjusting the separator, lines can be combined in different ways. For example, with a comma and a space:
const parts = ['JavaScript', 'PHP', 'Python'];
const output = parts.join(', ');
console.log(output); // => JavaScript, PHP, Python
If each word has to be printed on a new line, we use the line feed character '\n'
as a separator:
const parts = ['JavaScript', 'PHP', 'Python'];
// now each word will start on a new line
const output = parts.join('\n');
console.log(output); // =>
// JavaScript
// PHP
// Python
The last example is especially important. Beginners often make the mistake of adding a line break when the array is formed, rather than in join()
. Look at the example with our buildHTMLList()
function:
// Incorrect
const parts = [];
for (const item of coll) {
parts.push(`\n<li>${item}</li>`);
}
const innerValue = parts.join(''); // no separator
// Correct
const parts = [];
for (const item of coll) {
parts.push(`<li>${item}</li>`);
}
const innerValue = parts.join('\n'); // line break
Recommended materials
For full access to the course you need a professional subscription.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.