Last Updated: February 25, 2016
·
4.292K
· maciejsmolinski

Easy string formatting with JavaScript // Ember.js

If you're familiar with Ember's Ember.String.fmt function, you will quickly understand how this works:

"Hello %@ %@".fmt("John", "Doe");
// "Hello John Doe"

"Hello %@2, %@ 1".fmt("John", "Doe");
// "Hello Doe, John"

Behind the scenes it calls:

Ember.String.fmt("Hello %@ %@",   ["John", "Doe"]);
Ember.String.fmt("Hello %2 %@ 1", ["John", "Doe"]);

Do you think we could get rid of these square brackets so it feels more natural and could be used as a helper function rather than polluting String's prototype? We definitely could!

Ember.String.fmt("Hello %@ %@",     "John", "Doe");
Ember.String.fmt("Hello %@2, %@ 1", "John", "Doe");

Doesn't it read well? Here's the implementation:

Ember.String.fmt = function (string /*, arg1, arg2, ..., argn */) {
  var formats;
  var index;

  formats = Array.prototype.slice.call(arguments, 1);
  index   = 0;

  return string.replace(/%@([0-9]+)?/g, function (match, argumentIndex) {
    argumentIndex = (argumentIndex) ? parseInt(argumentIndex, 10) - 1 : index++;
    match = formats[argumentIndex];

    return ((match === null) ? '(null)' : (match === undefined) ? '' : match).toString();
  });
};

The key thing here is:

Array.prototype.slice.call(arguments, 1);

It simply converts arguments object to an array and removes first element (which is the string we want to format).

"John", "Doe" behind the scenes becomes an array again but API definitely feels more natural and reads well without square brackets! That was simple, wasn't it?