0

So I'm a newbie in javascript and I ran into this:

 /**
 * Replaces %1, %2 and so on in the string to the arguments.
 *
 * @method String.prototype.format
 * @param {Any} ...args The objects to format
 * @return {String} A formatted string
 */
String.prototype.format = function() {
    var args = arguments;
    return this.replace(/%([0-9]+)/g, function(s, n) {
        return args[Number(n) - 1];
    });
};

Can you guys help me figuring out what these couple of things mean please :)

Firstly, I don't understand what does "arguments" in "var args = arguments;" is supposed to be, what type it is? I don't understand what it does here. Secondly, what does "/%([0-9]+)/g" does? I can't understand any of that. And thirdly, how does that functions do what it says it does? I'm confused in all that. Thank you!

2
  • 1
    The part in the replace is called a regex. It's a special language used to parse text. The arguments is a special implicit variable available in functions that hold all the passed arguments. See the dupe above for an explanation. Also, please only ask 1 question per question. Commented Oct 7, 2017 at 21:56
  • 1) Google "arguments object". 2) That's a regular expression, understanding regexp syntax is key to understand that part. 3) Look for anonymus functions. Commented Oct 7, 2017 at 21:56

1 Answer 1

2

The arguments object is a special object that is created for every function invocation. Read more about it in the documentation:

The arguments object is a local variable available within all (non-arrow) functions. You can refer to a function's arguments within the function by using the arguments object. This object contains an entry for each argument passed to the function, the first entry's index starting at 0.

/%([0-9]+)/g is a regular expression literal. Such literals are distinguished by their / delimiters, just like quotes denote a string literal. Regular expressions are a language on their own, and are used in other language environments as well. They are used to find patterns in strings, and thus are a more powerful way to search things than .indexOf can offer. Read about it in the documentation.

Here is a break-down of that regular expression:

  • /: the delimiter: this is not part of the regular expression, but just tells Javascript that this is a regular expression literal

  • %: will match a literal percentage symbol.

  • ( ): A capture group. Whatever is matched by the pattern within these parentheses can be retrieved later as a separate string value (in this case, in the callback function passed to replace)

  • [ ]: a collection of characters. The next character (after the percentage symbol) in the searched string should be one of them.

  • [0-9]: a digit.

  • +: the previous pattern can occur more than once, but at least once. So in this case there should be at least one digit, but more are allowed.

  • g: this is a modifier to the regular expression that will make it match all occurrences of the pattern, not only the first one.

Maybe also mention this, which is the string on which this format method is called. Which string that is, is only known at the time the function is called.

The replace method can take a regular expression as its first argument, and in this case it looks for patterns that start with a percentage symbol followed by a non-signed integer number.

In this code the replace method also gets a callback function passed to it. This function will be called for every match that is found in the string. The value returned by that string will be used as replacement string for what was found. So this means all those %nn substrings will be replaced by something taken from the arguments object.

In this case the callback function is called with two arguments: the first one is the matched string, for example %1, and the second one is the first capture group (see parentheses in the regular expression): this is the same as the first argument, but without the %.

The Number function will convert the string of digit(s) to a number. As %1 should refer to the first argument, and the first argument has index 0, one has to be subtracted from that number in order to get the right index in the args array-like object.

Debug

You could place some console.log() statements in that code to get a better grip of what is happening, for instance like this:

String.prototype.format = function() {
    var args = arguments;
    console.log('arguments:', JSON.stringify(args));
    console.log('string to deal with: ' + this);
    return this.replace(/%([0-9]+)/g, function(s, n) {
        console.log('found:', s, 'with digit(s)', n);
        console.log('replacing that with argument at index:', (Number(n) - 1), 'which is', args[Number(n) - 1]);
        return args[Number(n) - 1];
    });
};

// Run the above method
var result = "My name is %1 and I am %2 years old.".format("Maria", 24);
console.log('final result:', result);

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much!!! I'll study about these regular expression literals, they seem very useful!
Wow there's a followup answer update! It has become very clear to me what is happening, you have helped me tremendously, thank you for taking the time! I'm very grateful.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.