1

How might this be improved, as it pertains to the loop and the regex replace?

var properties = { ... };
var template = element.innerHTML;

for (var name in properties) {
    template = template.replace
        (new RegExp('\\${' + name + '}', 'gm'), properties[name]);
}

element.innerHTML = template;

Is there a way I could get all the matches for /\$\{\w+\}/gm and just use those to build a new string once for the entire operation?

3 Answers 3

3

I agree with Jason and Hans WRT not bothering with this from a performance perspective.

But, i would have written it differently in the first place:

element.innerHTML
  = template.replace(/[$][{](\w+)[}]/g, function(x,y){return properties[y]||x;})

Some things to keep in mind

  1. If at all possible, you want to avoid looping over the creation of a RegExp for each iteration. Compiling them is generally considered costly. Or even generalize that to any object creation. Though not at the cost of readability/maintainability.
  2. If you're creating RegExp dynamically, be sure the result is a RegExp, otherwise see #1 as you'll likely be able to apply it.
Sign up to request clarification or add additional context in comments.

8 Comments

I don't understand the function(x,y) part. The second parameter for RegEx() is the flags for the pattern, and the second parameter for replace() is the new string that returns.
the second parameter for replace is optionally a transformation function
you might want to return properties[y] || y; if you want to keep any symbols that aren't recognized
@JamesBrown: the RegExp was broken. The idea is sound though. @Jimmy: good idea...
@Jimmy: ...or maybe return properties[y] || x; to restore the full ${foo} sequence if there's no foo property. It effectively ignores invalid tags, which is what the OP's code does (and Hans's code does, too).
|
1

I'll bite ;-)

var properties = { ... };
var template = element.innerHTML;
element.innerHTML = template.replace (
    RegExp ('\\$\\{(' + getTags (properties).join ('|') +')\\}'),
    function (m0, tag) {return properties[tag];});

function getTags (obj) {
  var tags = [];
  for (var t in obj)
    hasOwnProperty (t) && tags.push (t);
  return tags;
}

Still loops through the tags of properties (in call on getTags) but creates only one regexp object and scans the template only once.

Note that the tags names in properties should not contain special regexp characters (like . or (etc.).

I'd agree with Jason though, probably not worth the effort unless there are lots of tags or the template is very large.

Comments

0

Inefficient as it seems, I don't think you're going to do much better than that. So long as you're not replacing more than a few dozen tokens, I'd be surprised if this was actually a bottleneck.

If your profiler hasn't identified this as being a bottleneck, I definitely wouldn't spend time rewriting it. If nothing else, it's a lot more readable than your other idea, and in the end it's probably just as fast.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.