Home > Article > Web Front-end > Detailed explanation of JavaScript arguments object
Explained on MDN:
arguments is an array-like object. Represents the parameter list passed to a function.
Let’s first use an example to intuitively understand what arguments in JavaScript look like.
function printArgs() { console.log(arguments); } printArgs("A", "a", 0, { foo: "Hello, arguments" });
The execution result is:
["A", "a", 0, Object]
At first glance, the result is an array, but it is not a real array, so arguments is an array-like object (want to know about real arrays and array-like objects The difference between objects can be turned to the end).
Look at the content represented by arguments, which represents all the parameters passed into the function when the function is executed. In the above example, it represents the four parameters passed into the printArgs
function, which can be used respectively as arguments[0]
, arguments[1]
… Get a single parameter.
arguments is an array-like object, which contains a length
attribute, which can be used arguments. length
to get the number of parameters passed into the function.
function func() { console.log("The number of parameters is " + arguments.length); } func(); func(1, 2); func(1, 2, 3);
The execution results are as follows:
The number of parameters is 0 The number of parameters is 2 The number of parameters is 3
Usually use the following method to convert arguments into an array:
Array.prototype.slice.call(arguments);
There is another Shorter way of writing:
[].slice.call(arguments);
Here, the slice method of the empty array is simply called, without being called from the prototype level of Array.
Why can the above two methods be converted?
First of all, the result obtained by the slice method is an array, and the parameter is arguments. In fact, any object that meets certain conditions can be converted into an array by the slice method. Let’s look at an example:
const obj = { 0: "A", 1: "B", length: 2 }; const result = [].slice.call(obj); console.log(Array.isArray(result), result);
The execution result is:
true ["A", "B"]
As can be seen from the above example, the conditions are: 1) The attribute is 0, 1, 2...; 2) It has the length attribute;
In addition, one thing to note is that the arguments of the function cannot be leaked or passed out. What does that mean? Look at the following examples of leaked arguments:
// Leaking arguments example1: function getArgs() { return arguments; } // Leaking arguments example2: function getArgs() { const args = [].slice.call(arguments); return args; } // Leaking arguments example3: function getArgs() { const args = arguments; return function() { return args; }; }
The above approach directly leaks the arguments object of the function. The final result is that the V8 engine will skip optimization, resulting in considerable performance loss.
You can do this:
function getArgs() { const args = new Array(arguments.length); for(let i = 0; i < args.length; ++i) { args[i] = arguments[i]; } return args; }
That’s very curious. Every time we use arguments, the first step is usually to convert them into an array. At the same time, improper use of arguments can easily lead to performance losses. , so why not design arguments directly as array objects?
This needs to start from the beginning of this language. arguments were introduced in the early days of the language, when the Array object had four methods: toString, join, reverse, and sort. The big reason arguments inherits from Object is that these four methods are not needed. Now, Array has added many powerful methods, such as forEach, map, filter, etc. So why not let arguments re-inherit from Array in the new version? In fact, this was included in the ES5 draft, but for the sake of forward compatibility, it was ultimately rejected by the committee.
In strict mode and non-strict mode, the results of modifying the function parameter value are different. Look at the following two examples:
function foo(a) { "use strict"; console.log(a, arguments[0]); a = 10; console.log(a, arguments[0]); arguments[0] = 20; console.log(a, arguments[0]); } foo(1);
Output:
1 1 10 1 10 20
Another example of non-strict mode:
function foo(a) { console.log(a, arguments[0]); a = 10; console.log(a, arguments[0]); arguments[0] = 20; console.log(a, arguments[0]); } foo(1);
The output result is:
1 1 10 10 20 20
From As can be seen from the above two examples, in strict mode, the parameters in the function are not related to the arguments object, and modifying one value will not change the other value. In non-strict mode, the two will affect each other.
The following is the recommended practice for passing parameters from one function to another function.
function foo() { bar.apply(this, arguments); } function bar(a, b, c) { // logic }
There are overloading in many languages, but not in JavaScript. Let’s look at an example first:
function add(num1, num2) { console.log("Method one"); return num1 + num2; } function add(num1, num2, num3) { console.log("Method two"); return num1 + num2 + num3; } add(1, 2); add(1, 2, 3);
The execution result is:
Method two Method two
So, in JavaScript, functions do not make different calls based on different parameters.
Is there no overloading in JavaScript? No, we can use arguments to simulate overloading. Still the above example.
function add(num1, num2, num3) { if (arguments.length === 2) { console.log("Result is " + (num1 + num2)); } else if (arguments.length === 3) { console.log("Result is " + (num1 + num2 + num3)); } } add(1, 2); add(1, 2, 3)
The execution results are as follows:
Result is 3 Result is 6
Directly use the chestnut:
function func() { console.log(...arguments); } func(1, 2, 3);
The execution result is:
1 2 3
Succinctly speaking, the expansion operator can expand arguments into independent parameters.
It’s still the same as before:
function func(firstArg, ...restArgs) { console.log(Array.isArray(restArgs)); console.log(firstArg, restArgs); } func(1, 2, 3);
The execution result is:
true 1 [2, 3]
As can be seen from the above results, the Rest parameter indicates that in addition to clear Specify the remaining parameter set, type is Array.
Chestnut:
function func(firstArg = 0, secondArg = 1) { console.log(arguments[0], arguments[1]); console.log(firstArg, secondArg); } func(99);
The execution result is:
99 undefined 99 1
It can be seen that the default parameters have no effect on arguments. Arguments still only represent the calling function. All parameters passed in.
Array.from()
is a very recommended method, which can convert all array-like objects into arrays.
Arrays have one basic feature: index. This is something that ordinary objects don’t have.
const obj = { 0: "a", 1: "b" }; const arr = [ "a", "b" ];
我们利用 obj[0]
、arr[0]
都能取得自己想要的数据,但取得数据的方式确实不同的。obj[0]
是利用对象的键值对存取数据,而arr[0]
却是利用数组的索引。事实上,Object 与 Array 的唯一区别就是 Object 的属性是 string,而 Array 的索引是 number。
下面看看类数组对象。
伪数组的特性就是长得像数组,包含一组数据以及拥有一个 length 属性,但是没有任何 Array 的方法。再具体的说,length 属性是个非负整数,上限是 JavaScript 中能精确表达的最大数字;另外,类数组对象的 length 值无法自动改变。
如何自己创建一个类数组对象?
function Foo() {} Foo.prototype = Object.create(Array.prototype); const foo = new Foo(); foo.push('A'); console.log(foo, foo.length); console.log("foo is an array? " + Array.isArray(foo));
执行结果是:
["A"] 1 foo is an array? false
也就是说 Foo 的示例拥有 Array 的所有方法,但类型不是 Array。
如果不需要 Array 的所有方法,只需要部分怎么办呢?
function Bar() {} Bar.prototype.push = Array.prototype.push; const bar = new Bar(); bar.push('A'); bar.push('B'); console.log(bar);
执行结果是:
Bar {0: "A", 1: "B", length: 2}
以上就是JavaScript arguments 对象详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!