The first thing I'd do is check whether the temporary strings were actually causing a problem for my page/app, because JavaScript engines are extremely good at optimizing common issues like lots of temporary strings, especially in cases like your maskOutput where the string is the result of string concatenation. (V8, the engine in Chrome and elsewhere, does it when necessary by combining partial strings into a linked list.) It seems unlikely that the string concatenation in your maskOutput function is a bottleneck for your page/app. It used to be fairly standard practice that you'd see code building up a large string by using an array and then .join("") at the end, because it was faster circa 2009, but JavaScript engines have moved on a lot since then and I remember it became faster to just use += on a string several years ago.
If there were some use case (memory pressure, whatever) where the temporary strings were a problem, you could use a plain array¹ of individual characters, converting once (from string to array) at the outset if needed (not in your case) and at the end (from array to string). But for a short string like the ones I imagine maskOutput handles, as you say, the overhead wouldn't be worth it.
But just for completeness:
function maskOutput(input, mask) {
const len = input.length;
let result = Array(len); // Some engines actually do optimize this
for (let i = 0; i < len; i++) {
if (mask[i] === 'X') { // No need for a method call
result[i] = "-";
} else {
result[i] = input[i];
}
}
return result.join("");
}
¹ Uint8Array would be a poor choice, because:
- Strings are made up of 16-bit values (UTF-16 code units). If you want to use a typed array,
Uint16Array would be more appropriate.
- Putting a value into a
Uint8Array/Uint16Array requires converting it from JavaScript's number type to an 8-bit/16-bit unsigned integer (and the converse on reading), which is really cheap but isn't free. And presumably you'd have to use charCodeAt to get the value to store.
+=is well-optimised in engines. Is this really a problem in your application, did you benchmark your current solution?String.replaceand a RegExp object, the RegExp would do the dirty work for you, and you would have created a single string only.Uint16Arrayif you want to go for that, it matches the JS string representation more closely.