简体   繁体   中英

Javascript: What parameters are being passed to function?

I'm trying to wrap my brain around closures. I've been reading Javascript: the Good Parts, and the author presents this code snippet for adding a 'deentityify' method to String objects, the idea being to decode HTML-enocoded symbols:

// the method method:
Function.prototype.method = function(name, func) {
        if (! this.prototype[name]) {
                this.prototype[name] = func;
                return this;
        }
}

String.method('deentityify', function() {

        // entity table: maps entity names
        // to characters:
        var entity = {
                quot: '"',
                lt: '<',
                gt: '>',
        };

        // Return the deentityify method:
        return function() {
                return this.replace(/&([^&;]+);/g,
                        // What are a & b, how are they getting passed?!
                        function (a, b) {
                                //  console.log added by me, unsuccessfully:
                                console.log('a = ' + a);
                                console.log('b = ' + b);
                                var r = entity[b];
                                return typeof r === 'string' ? r : a;
                        }
                );
        };
}());

So I understand most of what's going on here, except for the actual parameters being passed to the function defined as the second parameter of String.replace. How are 'a' and 'b' getting defined?

Directly calling '"'.deentityify() does not explicitly pass any parameters. So how are they defined? As a secondary question, why does console.log() not work for logging the values of a and b? Is there any way I can successfully log such variables?

Thanks for the help.

EDIT: ' not ' was previously missing from the last sentence, making meaning unclear.

The .replace() function can be called with a function as the second parameter. When you do that, the function is invoked after the regex successfully matches with parameters extracted from the matching process.

The first parameter is always the entire matched portion of the source string. Subsequent parameters represent the "capturing groups" from the regex.

In this case, the regular expression is /&([^&;]+);/g . That matches an ampersand followed by any number of characters other than ampersand or semicolon, followed by a semicolon. The characters between the leading ampersand and the trailing semicolon are "captured" because that part of the regular expression is parenthesized.

Thus, if the source string is

Hello &mdash; world!

then matching against that regular expression (once) would yield:

  • &mdash; as the overall matched string
  • mdash as the value of the first (and only, in this case) captured group.

Thus:

"Hello &mdash; world!".replace(/&([^&;]+);/g, function(all, group) {
  alert("entire match: " + all + " group: " + group);
});

would show a message according to what I listed above.

Now, on top of all that, the code in the question involves another layer of interesting behavior. The function that is actually passed to the method() function is not that big outer function, but the function that is returned from that. That returned function expects to be called such that this is a String instance; otherwise, the call to this.replace() won't work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM