JavaScript에서 함수에 대해 "무제한"변수를 허용하는 방법이 있습니까?
예:
load(var1, var2, var3, var4, var5, etc...)
load(var1)
JavaScript에서 함수에 대해 "무제한"변수를 허용하는 방법이 있습니까?
예:
load(var1, var2, var3, var4, var5, etc...)
load(var1)
답변:
물론, 그냥 arguments
물건을 사용하십시오 .
function foo() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
arguments
특별한 "Array-like"객체입니다. 즉, 길이는 있지만 다른 배열 함수는 없습니다. 자세한 내용은 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 를 참조하십시오.이 답변은 stackoverflow.com/a/13145228/1766230
length
속성 이있는 객체에서 작동하도록 정의되었습니다 . 여기에는 arguments
개체가 포함됩니다 . 이것을 알면 메소드 concat
가 호출 된 '배열' 의 복사본 을 반환 하므로 arguments
객체를 다음과 같이 실제 배열 로 쉽게 변환 할 수 있습니다 var args = [].concat.call(arguments)
. 어떤 사람들은 Array.prototype.concat.call
대신 에 사용하는 것을 선호 하지만, 나는 좋아요 []
, 그들은 짧고 달콤합니다!
[...arguments].join()
(대부분의) 최신 브라우저에서는 다음 구문을 사용하여 가변 개수의 인수를 사용할 수 있습니다.
function my_log(...args) {
// args is an Array
console.log(args);
// You can pass this array as parameters to another function
console.log(...args);
}
다음은 작은 예입니다.
function foo(x, ...args) {
console.log(x, args, ...args, arguments);
}
foo('a', 'b', 'c', z='d')
=>
a
Array(3) [ "b", "c", "d" ]
b c d
Arguments
0: "a"
1: "b"
2: "c"
3: "d"
length: 4
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters에 대한 설명서 및 추가 예제
또 다른 옵션은 컨텍스트 객체에서 인수를 전달하는 것입니다.
function load(context)
{
// do whatever with context.name, context.address, etc
}
이렇게 사용하세요
load({name:'Ken',address:'secret',unused:true})
이것은 원하는만큼 명명 된 인수를 추가 할 수 있다는 장점이 있으며, 함수는 적절하다고 판단되는대로 사용할 수 있습니다.
context
코드로 인수를 작성하고 사용하기 전에 전달할 수 있기 때문에 좋습니다 .
나는 가장 역동적 인 Ken의 대답에 동의하며 한 걸음 더 나아가고 싶습니다. 다른 인수로 여러 번 호출하는 함수 인 경우 Ken의 디자인을 사용하지만 기본값을 추가하십시오.
function load(context) {
var defaults = {
parameter1: defaultValue1,
parameter2: defaultValue2,
...
};
var context = extend(defaults, context);
// do stuff
}
이 방법으로 매개 변수가 많지만 함수를 호출 할 때마다 매개 변수를 설정할 필요가없는 경우 기본값이 아닌 값을 지정하기 만하면됩니다. extend 메소드의 경우 jQuery의 extend 메소드 ( $.extend()
)를 사용하거나 직접 작성하거나 다음을 사용할 수 있습니다.
function extend() {
for (var i = 1; i < arguments.length; i++)
for (var key in arguments[i])
if (arguments[i].hasOwnProperty(key))
arguments[0][key] = arguments[i][key];
return arguments[0];
}
컨텍스트 객체를 기본값과 병합하고 객체의 정의되지 않은 값을 기본값으로 채 웁니다.
_.defaults()
방법은 지정된 인수와 기본 인수를 병합하는 매우 좋은 대안입니다.
이미 언급했듯이 arguments
객체를 사용하여 가변 개수의 함수 매개 변수를 검색 할 수 있습니다 .
동일한 인수로 다른 함수를 호출하려면을 사용하십시오 apply
. arguments
배열 로 변환 하여 인수를 추가하거나 제거 할 수도 있습니다 . 예를 들어이 함수는 콘솔에 로깅하기 전에 텍스트를 삽입합니다.
log() {
let args = Array.prototype.slice.call(arguments);
args = ['MyObjectName', this.id_].concat(args);
console.log.apply(console, args);
}
비록 이름있는 인수 접근법이 유용하고 유연하다는 데 동의하지만 (순서에 신경 쓰지 않는 한 인수가 가장 쉬운 경우는 아니지만) mbeasley 접근법의 비용 (기본값 및 확장 사용)에 대해 우려합니다. 이는 기본값을 가져 오는 데 드는 막대한 비용입니다. 먼저, 기본값은 함수 내에서 정의되므로 모든 호출에서 다시 채워집니다. 둘째, ||를 사용하여 명명 된 값을 쉽게 읽고 기본값을 동시에 설정할 수 있습니다. 이 정보를 얻기 위해 또 다른 새 객체를 만들어 병합 할 필요가 없습니다.
function load(context) {
var parameter1 = context.parameter1 || defaultValue1,
parameter2 = context.parameter2 || defaultValue2;
// do stuff
}
이것은 대략 같은 양의 코드 (약간 더 많을 수도 있음)이지만 런타임 비용의 일부 여야합니다.
(parameter1=context.parameter1)===undefined && (parameter1=defaultValue1)
또는 적은 코드 량을 위해 다음과 같은 작은 도우미 기능이 있습니다 : function def(providedValue, default) {return providedValue !== undefined ? providedValue : defaultValue;} var parameter1 = def(context.parameter1, defaultValue1)
대체 패턴을 제공하십시오. 그러나 요점은 여전히 설명합니다 . 모든 함수 호출에 대해 추가 객체 를 만들고 값 비싼 루프를 실행하여 몇 가지 기본값을 설정하는 것은 엄청난 양의 오버 헤드입니다.
@roufamatic은 arguments 키워드를 사용하고 @Ken은 사용을위한 객체의 훌륭한 예를 보여 주었지만이 인스턴스에서 진행중인 일을 진정으로 다루지 않았으며 미래 독자를 혼란스럽게하거나 기능을 명시 적으로 명시하지 않는 나쁜 습관을 심을 수 있습니다 / method는 다양한 양의 인수 / 매개 변수를 사용합니다.
function varyArg () {
return arguments[0] + arguments[1];
}
다른 개발자가 코드를 살펴보면이 함수가 매개 변수를 사용하지 않는다고 가정하는 것이 매우 쉽습니다. 특히 그 개발자가 arguments 키워드에 특권이 없다면 . 이 때문에 스타일 가이드 라인을 따르고 일관성을 유지하는 것이 좋습니다. 모든 예에서 Google을 사용합니다.
동일한 함수에 변수 매개 변수가 있다고 명시 적으로 설명하겠습니다.
function varyArg (var_args) {
return arguments[0] + arguments[1];
}
데이터 맵의 유일한 승인되고 고려되는 모범 사례 방법이므로 개체가 필요할 수 있습니다. 연관 배열은 눈살을 찌푸리고 낙담합니다.
SIDENOTE : arguments 키워드는 실제로 숫자를 키로 사용하여 객체를 반환합니다. 프로토 타입 상속도 객체 패밀리입니다. JS에서 올바른 배열 사용법은 응답 끝을 참조하십시오.
이 경우에도 명시 적으로 명시 할 수 있습니다. 참고 :이 명명 규칙은 Google에서 제공하지 않지만 param 유형의 명시 적 선언의 예입니다. 코드에서보다 엄격한 형식의 패턴을 만들려는 경우 중요합니다.
function varyArg (args_obj) {
return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});
이것은 기능과 프로그램의 요구에 따라 다릅니다. 예를 들어 전달 된 모든 인수에서 반복 프로세스를 기반으로 값 기반을 반환하려는 경우 인수 키워드를 사용하는 것이 가장 확실 합니다. 인수에 대한 정의와 데이터의 매핑이 필요한 경우 객체 방법을 사용하는 것이 좋습니다. 두 가지 예를 살펴보면 끝났습니다!
function sumOfAll (var_args) {
return arguments.reduce(function(a, b) {
return a + b;
}, 0);
}
sumOfAll(1,2,3); // returns 6
function myObjArgs(args_obj) {
// MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
if (typeof args_obj !== "object") {
return "Arguments passed must be in object form!";
}
return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old
답변 위에서 언급했듯이 arguments 키워드는 실제로 객체를 반환합니다. 이 때문에 배열에 사용하려는 메소드를 호출해야합니다. 이것의 예 :
Array.prototype.map.call(arguments, function (val, idx, arr) {});
이를 피하려면 rest 매개 변수를 사용하십시오.
function varyArgArr (...var_args) {
return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5
arguments
함수 내 에서 객체를 사용하여 전달 된 모든 인수에 액세스 할 수 있습니다.