Each Javascript function can access a special variable - arguments within its scope. This variable contains a list of all parameters passed to the function.
The arguments object is not an array. Although syntactically it has the same place as an array, for example it has the length property. But it is not inherited from Array.prototype, in fact, it is an object.
Therefore, we cannot directly use some array methods for arguments, such as push, pop or slice, etc. So in order to use these methods, we need to convert it into a real array.
Convert to an array
The following code will return an array containing all elements of the arguments object.
Array.prototype.slice.call(arguments);
Because the conversion speed is very slow, this is not recommended in programs with strict performance requirements.
Pass parameters
Here is a more recommended method to pass the arguments object from one function to another.
The code copy is as follows:
function foo() {
bar.apply(null, arguments);
}
function bar(a, b, c) {
// do stuff here
}
There is another clever method, which is to quickly create an unbinding outer method using call and apply at the same time.
The code copy is as follows:
function Foo() {}
Foo.prototype.method = function(a, b, c) {
console.log(this, a, b, c);
};
// Create an unbound version of "method"
// It takes the parameters: this, arg1, arg2...argN
Foo.method = function() {
// Result: Foo.prototype.method.call(this, arg1, arg2... argN)
Function.call.apply(Foo.prototype.method, arguments);
};
The relationship between function parameters and arguments attributes
The arguments object creates getter and setter methods for both its own properties and function parameters.
Therefore, modifying the formal parameters of the function will affect the property values of the corresponding arguments object and vice versa.
The code copy is as follows:
function foo(a, b, c) {
arguments[0] = 2;
a; // 2
b = 4;
arguments[1]; // 4
var d = c;
d = 9;
c; // 3
}
foo(1, 2, 3);
Performance issues
arguments will not be created in only two cases, one is declared as a local variable inside the function, and the other is used as a formal parameter of the function. In other cases, the arguments object will always be created.
Since getter and setter methods are always created with the creation of arguments objects, using arguments has little effect on performance itself.
However, there is a situation that seriously affects Javascript's performance, which is to use arguments.callee.
The code copy is as follows:
function foo() {
arguments.callee; // do something with this function object
arguments.callee.caller; // and the calling function object
}
function bigLoop() {
for(var i = 0; i < 100000; i++) {
foo(); // Would normally be inlined...
}
}
In the above code, the foo function is no longer a simple inline extension, because it needs to know itself and its caller. This not only offsets the performance improvements brought by inline extensions, but also undermines the encapsulation of the function, because the function itself may need to rely on a specific calling background.
Therefore, it is recommended that you try not to use arguments.callee.
The above is all about the Javascript arguments object. Do you know it thoroughly? Simply put
arguments refer to the parameter object of the function (refers to the actual passed parameters)
arguments.length refers to the length of the parameter object of the function.
arguments[i] refers to the value of the i-th parameter (the first one is 0)