Home > Web Front-end > JS Tutorial > body text

A comprehensive introduction to the JavaScript arguments object

高洛峰
Release: 2016-10-13 09:10:49
Original
895 people have browsed it

1. What are arguments

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" });
Copy after login

The execution result is:

["A", "a", 0, Object]
Copy after login

At first glance, the result is an array, but it is not a real array, so arguments is an array-like object (if you want to know the difference between a real array and an array-like object, you can scroll to the end ).

Look again 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. You can use arguments[0], arguments[1]... to obtain a single parameter.

2. arguments operation

2.1 arguments length

arguments is an array-like object, which contains a length property. You can use 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);
Copy after login

The execution result is as follows:

The number of parameters is 0 
 
The number of parameters is 2 
 
The number of parameters is 3
Copy after login

2.2 arguments to array

Usually use the following method to convert arguments into an array:

Array.prototype.slice.call(arguments);
Copy after login

There is also a shorter way of writing:

[].slice.call(arguments);
Copy after login

Here, just simply call The slice method of an empty array is not 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. Take an example:

const obj = { 0: "A", 1: "B", length: 2 }; 
 
const result = [].slice.call(obj); 
 
console.log(Array.isArray(result), result);
Copy after login

The execution result is:

true ["A", "B"]
Copy after login

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, there is a need The important thing to note is that the arguments of the function cannot be leaked or passed out. What does it mean? Look at the following examples of leaking 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; 
 
    }; 
 
}
Copy after login

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; 
 
}
Copy after login

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? What about array objects?

This needs to be talked about 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 why 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.

2.3 Modify arguments value

In strict mode and non-strict mode, the results of modifying function parameter values ​​are different. Look at the two examples below:

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);
Copy after login

Output:

1 1 
 
10 1 
 
10 20
Copy after login

Another example in 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);
Copy after login

The output is:

1 1 
 
10 10 
 
20 20
Copy after login

As can be seen from the above two examples, in strict mode, the function The parameters in 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.

2.4 Passing parameters from one function to another

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 
 
}
Copy after login

2.5 arguments and overloading

Overloading is available 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);
Copy after login

The execution result is:

Method two 
 
Method two
Copy after login

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)
Copy after login

The execution result is as follows:

Result is 3 
 
Result is 6
Copy after login

3. Arguments in ES6

3.1 Expansion operator

Directly to the chestnut:

function func() { 
 
console.log(...arguments); 
 
} 
 
func(1, 2, 3);
Copy after login

The execution result is:

1 2 3
Copy after login

Succinctly speaking, the expansion operator can expand arguments into independent parameters.

3.2 Rest parameter

is still the best example:

function func(firstArg, ...restArgs) { 
 
console.log(Array.isArray(restArgs)); 
 
console.log(firstArg, restArgs); 
 
} 
 
func(1, 2, 3);
Copy after login

The execution result is:

true 
 
1 [2, 3]
Copy after login

From the above results, it can be seen that the Rest parameter represents the remaining parameter set except the explicitly specified one, and the type is Array.

3.3 Default parameters

Chestnut:

function func(firstArg = 0, secondArg = 1) { 
 
console.log(arguments[0], arguments[1]); 
 
console.log(firstArg, secondArg); 
 
} 
 
func(99);
Copy after login

The execution result is:

99 undefined 
 
99 1
Copy after login

It can be seen that the default parameters have no effect on arguments, and arguments still only represent all the parameters passed in when calling the function.

3.4 arguments to array

Array.from() is a very recommended method, which can convert all array-like objects into arrays.

4. Arrays and array-like objects

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" ];
Copy after login

We can use obj[0] and arr[0] to get the data we want, but the ways to get the data are really different. obj[0] uses the key-value pair of the object to access data, while arr[0] uses the index of the array. In fact, the only difference between Object and Array is that Object's properties are strings, while Array's indexes are numbers.

Let’s take a look at array-like objects.

伪数组的特性就是长得像数组,包含一组数据以及拥有一个 length 属性,但是没有任何 Array 的方法。再具体的说,length 属性是个非负整数,上限是 JavaScript 中能精确表达的最大数字;另外,类数组对象的 length 值无法自动改变。

如何自己创建一个类数组对象?

function Foo() {} 
 
Foo.prototype = Object.create(Array.prototype); 
 
const foo = new Foo(); 
 
foo.push(&#39;A&#39;); 
 
console.log(foo, foo.length); 
 
console.log("foo is an array? " + Array.isArray(foo));
Copy after login

执行结果是:

["A"] 1 
 
foo is an array? false
Copy after login

也就是说 Foo 的示例拥有 Array 的所有方法,但类型不是 Array。

如果不需要 Array 的所有方法,只需要部分怎么办呢?

function Bar() {} 
 
Bar.prototype.push = Array.prototype.push; 
 
const bar = new Bar(); 
 
bar.push(&#39;A&#39;); 
 
bar.push(&#39;B&#39;); 
 
console.log(bar);
Copy after login

执行结果是:

Bar {0: "A", 1: "B", length: 2}
Copy after login

参考:

JavaScript中的数组与伪数组的区别

MDN arguments

Avoid modifying or passing arguments into other functions — it kills optimization

Optimization killers

Why isn't a function's arguments object an array in Javascript?

arguments 对象

Advanced Javascript: Objects, Arrays, and Array-Like objects

JavaScript 特殊对象 Array-Like Objects 详解

What is a good way create a Javascript array-like object?


source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!