2014-11-02 4 views
3

함수가 'arguments'객체를 사용하는 가장 좋은 방법은 무엇입니까?
이것은 분명히 의견을 기반으로하지만 어떤 규칙이 있습니까? 언제 인수 배열을 사용하는 것이 더 좋을까요?함수가 'arguments'객체를 사용하는 가장 명확한 방법은 무엇입니까?

몇 가지 예 :

// Function takes n arguments and makes them pretty. 
function manyArgs() { 
    for (var i = 0; i < arguments.length; i++) 
    console.log(arguments[i]); 
} 

function manyArgs(/* n1 , n2, ... */) 

function manyArgs(n1 /*, n2, ... */) 

function manyArgs(argArray) 
+2

'arguments' 객체의 [성능 영향] (https://github.com/petkaantonov/bluebird/wiki/Optimization-killers)에 유의하십시오. – Pointy

+0

개인적으로 Google 스타일 가이드/클로저 컴파일러에서 권장하는대로'var_args'를 사용합니다. 이것이 사실상 처음으로 주석 처리되지 않은 함수를 보는 사람에게 유용한 힌트를 제공한다면 누가 알겠습니까. –

+0

@Pointy 링크에 감사드립니다. 재미있는 것들. –

답변

0
// Using ES6 syntax ... 
var foo = function(/*...args*/){ 
    // shim Array.from, then 
    var args = Array.from(arguments); 
    // or 
    var args = [].slice.call(arguments); 
}; 
+0

ES6 구문을 사용한다면'var foo = function (... args)'라고 말할 수 있습니다. 또한 함수의 가변성을 문서화하는 방법에 대한 OP 문제를 깔끔하게 해결합니다. –

+1

@torazaburo 유감스럽게도, 함수의 정의는 최종 사용자가 정의를 읽지 않는 한 가변 인수를 사용한다는 표시가 아닙니다 (최종 사용자는 그렇지 않을 가능성이 큽니다). 함수 호출은 해당 함수가 함수 정의가 아니라 가변적임을 나타냅니다. 모든 사용자가 함수 정의를 사용하기 전에 함수 정의를 읽을 수는 없습니다. 문서화가 확실히 도움이 될 것입니다. 그리고 variadic 함수에 대한 특별한 명명 규칙을 제외하고는 문서화 만이 가능한 다른 옵션이라고 생각합니다. 질문의 의견을 바탕으로. –

+0

@AaditMShah'add (1,2,3)'가 누군가를 혼란스럽게하는지 의심 스럽지만 기본적으로 옳다. 어쨌든, 의견을 바탕으로 결론에 투표. –

4

나는 자바 스크립트에서 가변 인수를 사용하지 않습니다. 코드를 구조화하는 더 좋은 방법이 많이 있습니다. 예를 들어 다음과 같이 코드를 다시 작성합니다.

[1,2,3,4,5].forEach(log); // instead of manyArgs(1,2,3,4,5); 

function log(a) { 
    console.log(a); 
} 

명확하고 간결합니다.

또 다른 예를 들어, 당신은 자바 스크립트의 번호 목록의 합계를 찾으려는 경우 :

[1,2,3,4,5].reduce(add, 0); // instead of add(1,2,3,4,5); 

function add(a, b) { 
    return a + b; 
} 

내가 사용의 혜택을 볼 수 없습니다 코드를 구성 할 수 있도록 많은 유용한 추상화가있다 variadic 논증.

나는 그러나 기본 값에 대한 arguments 객체를 사용합니까 :

function foo(a,b,c) { 
    switch (arguments.length) { 
    case 0: a = "default argument for a"; 
    case 1: b = "default argument for b"; 
    case 2: c = "default argument for c"; 
    } 

    // do something with a, b & c 
} 

은 따라서 당신에게 내 조언은 전혀 가변 인수를 사용하지하는 것입니다. 코드에 대한 더 나은 추상화를 찾으십시오. 저는 JavaScript로 프로그래밍 한 8 년 동안 가변 인수를 사용할 필요가 없었습니다.


편집 : 내가 코드를 작성에 더 많은 기능 접근법을 사용하여 옹호한다. 우리는 코드를보다 간결하게 태닝을 사용할 수 있습니다

var reduce = curry(function (func, acc, a) { 
    var index = 0, length = a.length; 
    while (index < length) acc = func(acc, a[index++]); 
    return acc; 
}); 

var sum = reduce(add, 0); 

sum([1,2,3,4,5]); // instead of add(1,2,3,4,5); 

function add(a, b) { 
    return a + b; 
} 
Math.max에 대한 유사

Array.prototype.concat : 관해서

var reduce1 = curry(function (func, a) { 
    if (a.length === 0) 
     throw new Error("Reducing empty array."); 
    return reduce(func, a[0], a.slice(1)); 
}); 

var maximum = reduce1(max); 

maximum([1,2,3,4,5]); // instead of Math.max(1,2,3,4,5); 

function max(a, b) { 
    return a > b ? a : b; 
} 

var concat = reduce(function (a, b) { 
    return a.concat(b); 
}, []); 

concat([[1,2],[3,4],[5,6]]) // instead of [1,2].concat([3,4],[5,6]) 

function curry(func, length, args) { 
    switch (arguments.length) { 
    case 1: length = func.length; 
    case 2: args = []; 
    } 

    var slice = args.slice; 

    return function() { 
     var len = arguments.length; 
     var a = args.concat(slice.call(arguments)); 
     if (len >= length) return func.apply(this, a); 
     return curry(func, length - len, a); 
    }; 
} 

는 다음과 같이 우리가 합의 예를 다시 작성할 수 있습니다 curry을 사용하여 Array.prototype.push, 새 배열을 만드는 대신 입력 배열을 변경하기 때문에 array.concat([element]) inste를 사용하는 것이 더 좋습니다. array.push(element)의 광고 :

var push = reduce(function (a, e) { 
    return a.concat([e]); 
}); 

push([1,2,3], [4,5]); // instead of [1,2,3].push(4, 5) 

그래서 코드를 작성의 장점이 방법이 무엇 :

  1. 커링이 굉장합니다. 그것은 당신이 오래된 것들에서 새로운 기능을 만들 수 있습니다.
  2. 가변 인수를 사용하는 대신 배열을 함수에 전달합니다. 따라서 함수가 arguments을 사용한다는 것을 나타내는 특별한 방법이 필요하지 않습니다.
  3. array이라는 배열의 합계를 찾아야한다고 가정 해 보겠습니다. 이 방법을 사용하면 sum(array)을 사용할 수 있습니다. 가변 인수를 사용하는 경우 add.apply(null, array)을 수행해야합니다.
  4. a, b & c의 합을 찾으려한다고 가정 해보십시오. add(a, b, c)과 비교하여 sum([a,b,c]) 만 있으면됩니다. 대괄호 ([])를 추가해야합니다. 그러나 이렇게하면 코드를 더 이해하기 쉬워집니다. zen of python에 따르면 “ 명시 적 암시 적보다 낫다 ”.

따라서 내 프로그램에서 가변 인수를 절대로 사용하지 않는 이유 중 일부입니다.

+0

+! 선택적 인수에 대한 switch/case/fallthough 패턴 용. –

+0

'a = a || "default"'를 사용할 수 없을 때 스위치로 좋은 트릭을. 나는'[1,2,3,4,5] .reduce (add, 0);보다 더 명백하게/읽을 수있는'add (1,2,3,4,5)'를 찾아야한다고 말해야한다. – Jonathan

+1

I Math.max','Array.push','Array.concat' 등의 디자이너들에게 즉시 연락하여 설계가 잘못되었다고 말해야한다고 생각해보십시오. –

0

가장 분명한 방법은, (그들이 식별자 뒤에 오는 "표시가"와 세 개의 점이라고합니다) CoffeeScriptTypeScript (그들은 "나머지 매개 변수"라고 곳 ES6에서 사용할 확산 연산자를 사용하는 것입니다).

// Function takes n arguments and makes them pretty. 
function manyArgs(...args) { 
    for (var i = 0; i < args.length; i++) 
     console.log(args[i]); 
} 

물론 사용할 수있는 환경에 있다면. 둘 다 자기 문서화가 더 우수하며 arguments으로 주변을 돌볼 필요가 없습니다.