배열로 변환
매개변수 전달
자동 업데이트
성능에 관한 진실
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 중국어 홈페이지(m.sbmmt.com)를 참고해주세요!