In each function, there is a variable named arguments, which stores the parameters of the current call in an array-like form. And it is not actually an array. Trying to use the typeof arguments statement will return "object" (object), so it cannot use methods such as push and pop like Array. Even so, its value can still be obtained using the subscript and the length attribute.
Writing flexible functions
Although it may seem unknown, arguments are indeed very useful objects. For example, you can have a function handle a variable number of arguments. In the base2 library written by Dean Edwards, there is a function called format that takes full advantage of this feature:
function format(string) {
var args = arguments;
var pattern = new RegExp("%([1-" arguments.length "])", "g ");
return String(string).replace(pattern, function(match, index) {
return args[index];
});
};
This function implements template replacement. You can use %1 to %9 tags in the places you want to dynamically replace, and then the remaining parameters will replace these places in sequence. For example:
format("And the %1 want to know whose %2 you %3", "papers", "shirt", "wear"); The above script will return
"And the papers want to know whose shirt you wear" . What needs to be noted here is that even in the format function definition, we only define a parameter named string. Javascript allows us to pass any number of parameters to a function, regardless of the number of parameters defined by the function itself, and save these parameter values in the arguments object of the called function.
Convert to an actual array
Although the arguments object is not a Javascript array in the true sense, we can use the slice method of the array to convert it into an array, similar to the following code
var args = Array.prototype.slice.call(arguments);
In this way, the array variable args contains the values contained in all arguments objects.
Create a function with preset parameters
Using the arguments object can reduce the amount of Javascript code we write. Below is a function called makeFunc that returns an anonymous function based on the function name you provide and any number of other parameters. When this anonymous function is called, the parameters of the original call are merged and passed to the specified function to run and then return its return value.
function makeFunc() {
var args = Array .prototype.slice.call(arguments);
var func = args.shift();
return function() {
return func.apply(null, args.concat(Array.prototype.slice. call(arguments)));
};
}
The first parameter of makeFunc specifies the name of the function that needs to be called (yes, there is no error checking in this simple example ), and delete it from args after retrieval. makeFunc returns an anonymous function that calls the specified function using the Function Object's apply method.
The first parameter of the apply method specifies the scope. Basically the scope is the called function. But that looks a bit complicated in this example, so we set it to null ; its second parameter is an array that specifies the parameters of the function it calls. makeFunc converts its own arguments and concatenates the arguments of the anonymous function before passing them to the called function.
There is a situation where the output template is always the same. In order to save using the format function mentioned above and specifying repeated parameters each time, we can use the makeFunc tool. It will return an anonymous function and automatically generate the content after the specified template:
var majorTom = makeFunc(format, "This is Major Tom to ground control. I'm %1.");
You can repeatedly specify the majorTom function like this:
majorTom("stepping through the door");
majorTom ("floating in a most peculiar way");
Then every time the majorTom function is called, it will fill in the specified template with the first specified parameter. For example, the above code returns:
"This is Major Tom to ground control. I'm stepping through the door."
"This is Major Tom to ground control. I'm floating in a most peculiar way."
Self-referential function
You may think this is cool, but don’t be too happy just yet, there will be a bigger surprise later. It (arguments) has another very useful attribute: callee. arguments.callee contains the referenced object of the currently called function. So what do we do with this thing? arguments.callee is a very useful anonymous function that calls itself.
There is a function named repeat below, whose parameters require a function reference and two numbers. The first number represents the number of runs, while the second function defines the time in milliseconds between runs. The following is the relevant code:
function repeat(fn, times , delay) {
return function() {
if(times-- > 0) {
fn.apply(null, arguments);
var args = Array.prototype.slice.call (arguments);
var self = arguments.callee;
setTimeout(function(){self.apply(null,args)}, delay);
}
};
}
The repeat function uses arguments.callee to obtain the current reference, saves it to the self variable, and then returns an anonymous function to re-run the originally called function. Finally, use setTimeout and an anonymous function to implement delayed execution.
As a simple explanation, for example, in a normal script, write the following simple function that provides a string and pops up a warning box:
function comms(s) {
alert(s);
}
Well, then I changed my mind. I want to write a "special version" of the function that will run three times with two seconds between each time. Then using my repeat function, you can do it like this:
var somethingWrong = repeat(comms, 3, 2000);
somethingWrong("Can you hear me, major tom?");
The result is as expected, popping up three times The warning box is delayed for two seconds each time.
Finally, even if arguments are not used often and may even seem a bit weird, its above-mentioned amazing functions (and not just these!) are worth getting to know.