>  기사  >  웹 프론트엔드  >  JavaScript 고급 시리즈 - 인수 객체

JavaScript 고급 시리즈 - 인수 객체

黄舟
黄舟원래의
2017-02-08 09:43:551130검색
  • 배열로 변환

  • 매개변수 전달

  • 자동 업데이트

  • 성능에 관한 진실

JavaScript의 모든 함수는 특수 변수 인수에 액세스할 수 있습니다. 이 변수는 이 함수에 전달된 모든 매개변수 목록을 유지합니다.

인수 변수가 배열(Array)이 아닙니다. 구문상으로는 배열 관련 속성 길이를 가지지만 Array.prototype에서 상속되지 않으며 실제로는 객체입니다.

(참고: 인수는 함수 내에서 변수로 정의되어 있으므로 var 키워드를 통해 인수를 정의하거나 인수를 형식 매개변수로 선언하면 네이티브 인수가 생성되지 않습니다.)

따라서 push, pop, Slice 등의 표준 배열 방식은 인수 변수에 사용할 수 없습니다. for 루프를 사용하여 순회하는 것도 가능하지만 배열 방식을 더 잘 활용하려면 실제 배열로 변환하는 것이 가장 좋습니다.

배열로 변환

다음 코드는 인수 개체의 모든 요소를 ​​포함하는 새 배열을 생성합니다.

Array.prototype.slice.call(arguments);

이 변환은 느리므로 성능이 낮은 코드에서는 권장되지 않습니다.

매개변수 전달

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

function foo() {
    bar.apply(null, arguments);
}
function bar(a, b, c) {
    // 干活
}

또 다른 팁은 call과 Apply를 함께 사용하여 빠르게 바인딩 해제 래퍼를 만드는 것입니다.

function Foo() {}

Foo.prototype.method = function(a, b, c) {
    console.log(this, a, b, c);
};

// 创建一个解绑定的 "method"
// 输入参数为: this, arg1, arg2...argN
Foo.method = function() {

    // 结果: Foo.prototype.method.call(this, arg1, arg2... argN)
    Function.call.apply(Foo.prototype.method, arguments);
};

번역자 참고 사항: 위의 Foo.method 함수는 다음 코드와 동일한 효과를 갖습니다.

Foo.method = function() {
    var args = Array.prototype.slice.call(arguments);
    Foo.prototype.method.apply(args[0], args.slice(1));
}

arguments 객체를 내부 속성 및 함수 형식으로 자동 업데이트합니다. 매개변수는 getter 및 setter 메소드를 생성합니다.

따라서 형식 매개변수의 값을 변경하면 인수 객체의 값에 영향을 미치고 그 반대의 경우도 마찬가지입니다.

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)

성능의 진실

arguments 객체는 지역 변수와 형식 매개변수로 선언되는 두 가지 특별한 경우를 제외하고는 사용 여부에 관계없이 항상 생성됩니다.

인수의 getter 및 setter 메서드는 항상 생성되므로 인수를 사용해도 성능에 영향을 주지 않습니다. 인수 객체의 속성에 여러 번 액세스해야 하는 경우가 아니라면 말이죠.

번역자 주: MDC의 엄격 모드 인수에 대한 설명은 이해에 도움이 됩니다. 다음 코드를 참조하세요.

// 阐述在 ES5 的严格模式下 `arguments` 的特性
function f(a) {
  "use strict";
  a = 42;
  return [a, arguments[0]];
}
var pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);

그러나 실제로 심각한 문제가 발생하는 상황이 있습니다. 최신 JavaScript 엔진의 성능에 영향을 미칩니다. 이것은args.callee를 사용하고 있습니다.

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...
    }
}

위 코드에서 foo는 더 이상 단순한 인라인 함수 인라인이 아닙니다. 이는 인라인 함수의 성능 향상을 무효화할 뿐만 아니라 캡슐화를 깨뜨리므로 이제 함수는 특정 컨텍스트에 따라 달라질 수 있습니다.


따라서 Arguments.callee 및 해당 속성을 사용하지 않는 것이 좋습니다.

위 내용은 JavaScript 고급시리즈-인수객체 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.