JavaScript 인수 객체에 대한 자세한 설명

黄舟
풀어 주다: 2017-03-03 15:13:10
원래의
1229명이 탐색했습니다.

1. 인수란 무엇입니까

MDN은 다음과 같이 설명합니다.

인수는 배열과 유사한 객체입니다. 함수에 전달된 매개변수 목록을 나타냅니다.

먼저 예시를 통해 JavaScript의 인수가 어떤 모습인지 직관적으로 이해해 보겠습니다.

function printArgs() {
    console.log(arguments);
}
printArgs("A", "a", 0, { foo: "Hello, arguments" });
로그인 후 복사

실행 결과는 다음과 같습니다.

["A", "a", 0, Object]
로그인 후 복사

얼핏 결과는 배열이지만 실제 배열은 아니므로 인수는 배열과 유사한 객체입니다. 실제 배열과 배열 유사 객체 객체의 차이점은 끝까지 뒤집을 수 있습니다).

함수가 실행될 때 함수에 전달되는 모든 매개변수를 나타내는 인수로 표시되는 내용을 살펴보세요. 위의 예에서는 printArgs 함수에 전달된 4개의 매개변수를 나타냅니다. arguments[0], arguments[1]...을 사용하여 단일 매개변수를 얻을 수 있습니다.

2. 인수 연산

2.1 인수 길이

arguments는 length 속성을 ​​포함하는 배열과 유사한 객체입니다. 함수에 전달된 매개변수입니다. arguments.length

function func() {
    console.log("The number of parameters is " + arguments.length);
}

func();
func(1, 2);
func(1, 2, 3);
로그인 후 복사

실행 결과는 다음과 같습니다.

The number of parameters is 0
The number of parameters is 2
The number of parameters is 3
로그인 후 복사

2.2 인수를 배열로 변환

일반적으로 인수를 배열로 변환하려면 다음 방법을 사용합니다.

Array.prototype.slice.call(arguments);
로그인 후 복사

또 다른 짧은 작성 방법이 있습니다:

[].slice.call(arguments);
로그인 후 복사

여기서는 Array의 프로토타입 수준에서 호출하지 않고 빈 배열의 슬라이스 메서드를 간단히 호출합니다.

위 두 메소드를 왜 변환할 수 있나요?

우선, 슬라이스 메소드로 얻은 결과는 배열이고, 매개변수는 인수입니다. 실제로 특정 조건을 만족하는 객체는 슬라이스 메소드를 통해 배열로 변환될 수 있습니다. 예를 들면:

const obj = { 0: "A", 1: "B", length: 2 };
const result = [].slice.call(obj);
console.log(Array.isArray(result), result);
로그인 후 복사

실행 결과는 다음과 같습니다.

true ["A", "B"]
로그인 후 복사

위의 예에서 볼 수 있듯이 조건은 다음과 같습니다. 1) 속성은 0, 1, 2...; 2) 길이 속성을 가집니다.

추가로 한 가지 주의할 점은 함수의 인수가 유출되거나 전달될 수 없다는 것입니다. 그것은 무엇을 의미합니까? 다음 인수 누출 예를 살펴보세요.

// 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;
    };
}
로그인 후 복사

위 접근 방식은 함수의 인수 개체를 직접 누출합니다. 최종 결과는 V8 엔진이 최적화를 건너뛰어 상당한 성능 손실을 초래한다는 것입니다.

이렇게 할 수 있습니다:

function getArgs() {
    const args = new Array(arguments.length);
    for(let i = 0; i < args.length; ++i) {
        args[i] = arguments[i];
    }
    return args;
}
로그인 후 복사

아주 궁금합니다. 인수를 사용할 때마다 첫 번째 단계는 일반적으로 인수를 잘못 사용하면 성능이 저하될 수 있습니다. loss., 그렇다면 인수를 배열 객체로 직접 디자인하는 것은 어떨까요?

이것은 이 언어의 처음부터 시작해야 합니다. Array 객체에 toString, Join, reverse 및 sort의 네 가지 메서드가 있었던 언어 초기에 인수가 도입되었습니다. 인수가 Object에서 상속되는 가장 큰 이유는 이 네 가지 메서드가 필요하지 않기 때문입니다. 이제 Array에는 forEach, map, filter 등과 같은 강력한 메서드가 많이 추가되었습니다. 그렇다면 새 버전에서는 인수가 Array에서 다시 상속되도록 하는 것이 어떨까요? 실제로 이는 ES5 초안에 포함됐지만 향후 호환성을 위해 위원회에서 최종적으로 거부됐다.

2.3 인수 값 수정

엄격 모드와 비엄격 모드에서는 함수 매개 변수 값을 수정한 결과가 다릅니다. 다음 두 가지 예를 살펴보십시오.

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);
로그인 후 복사

출력:

1 1
10 1
10 20
로그인 후 복사

또 다른 비엄격 모드 예:

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);
로그인 후 복사

출력은 다음과 같습니다.

1 1
10 10
20 20
로그인 후 복사

From As 위의 두 예제에서 볼 수 있듯이 엄격 모드에서는 함수의 매개변수가 인수 객체와 관련이 없으며 한 값을 수정해도 다른 값은 변경되지 않습니다. 비엄격 모드에서는 둘이 서로 영향을 미칩니다.

2.4 한 함수에서 다른 함수로 매개변수 전달

다음은 한 함수에서 다른 함수로 매개변수를 전달할 때 권장되는 방법입니다.

function foo() {
    bar.apply(this, arguments);
}
function bar(a, b, c) {
    // logic
}
로그인 후 복사

2.5개 인수 및 오버로딩

오버로딩은 여러 언어에서 사용할 수 있지만 JavaScript에서는 사용할 수 없습니다. 먼저 예를 살펴보겠습니다.

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);
로그인 후 복사

실행 결과는 다음과 같습니다.

Method two
Method two
로그인 후 복사

따라서 JavaScript에서는 함수가 서로 다른 매개변수를 기반으로 서로 다른 호출을 하지 않습니다.

자바스크립트에는 오버로딩이 없나요? 아니요, 인수를 사용하여 오버로드를 시뮬레이션할 수 있습니다. 여전히 위의 예입니다.

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)
로그인 후 복사

의 실행 결과는 다음과 같습니다.

Result is 3
Result is 6
로그인 후 복사

3. ES6의 인수

3.1 확장 연산자

는 밤나무로 바로 이동합니다.

function func() {
    console.log(...arguments);
}

func(1, 2, 3);
로그인 후 복사

실행 결과는 다음과 같습니다.

1 2 3
로그인 후 복사

간단히 말하면 확장 연산자는 인수를 독립 매개변수로 확장할 수 있습니다.

3.2 Rest 매개변수

아직도 가장 좋은 예:

function func(firstArg, ...restArgs) {
    console.log(Array.isArray(restArgs));
    console.log(firstArg, restArgs);
}

func(1, 2, 3);
로그인 후 복사

실행 결과:

true
1 [2, 3]
로그인 후 복사

위 결과에서 볼 수 있듯이 나머지 매개변수는 나머지 매개변수 세트 지정을 지우는 것 외에 유형이 배열임을 나타냅니다.

3.3 기본 매개변수

Chestnut:

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

func(99);
로그인 후 복사

실행 결과는

99 undefined
99 1
로그인 후 복사

기본 매개변수는 인수에 아무런 영향을 미치지 않음을 알 수 있습니다. , 인수는 여전히 전달된 모든 매개변수를 호출하는 함수만 나타냅니다.

3.4 인수를 배열로 변환

은 배열과 유사한 모든 객체를 배열로 변환할 수 있는 매우 권장되는 방법입니다. Array.from()

4. 배열 및 배열 유사 객체

배열에는 인덱스라는 하나의 기본 기능이 있습니다. 이는 일반 물체에는 없는 것입니다.

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(&#39;A&#39;);
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(&#39;A&#39;);
bar.push(&#39;B&#39;);
console.log(bar);
로그인 후 복사

执行结果是:

Bar {0: "A", 1: "B", length: 2}
로그인 후 복사

 以上就是JavaScript arguments 对象详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿