가변인자 목록
자바스크립트가 지닌 유연하고 강력한 기능 중 하나는 함수가 임의 개수의 인자를 받을 수 있다는 것이다.
몇 가지 예제를 통하여 유연한 인자 목록이 제공하는 장점을 알아보자.
- 임의 개수의 인자를 받는 함수에 여러 개의 인자를 제공하는 방법
- 함수 오버로딩을 구현하기 위해서 가변인자 목록을 활용하는 방법
- 인자 목록이 지닌 length 프로퍼티에 대해 이해하고 활용하는 방법
자바스크립트는 함수 오버로딩을 제공하지 않는다. 그렇기 때문에 오버로딩이 제공하는 장점과 유사한 장점을 얻으려면 인자 목록의 유연함이 필요하다.
apply() 메서드를 이용해서 가변 길이의 인자를 전달하기
자바스크립트에서는 배열에서 최솟값이나 최댓값을 검색하는 기능이 없다. 유사한 기능으로 Math 객체에 있는 min(), max() 메서드가 있는데, 이 메서드는 배열이 아니라 가변인자 목록을 요구한다. (배열에 대한 최댓값이나 최솟값을 구하는 것은 존재하지 않음)
var biggest = Math.max(1,2);
var biggest = Math.max(1,2,5,10);
// 배열을 다룬다면 다음과 같이 할 수 밖에 없다.
var biggest = Math.max(list[0], list[1], list[2]);
배열을 가변인자 목록인 것처럼 사용할 수 있는 방법을 찾아보자
function smallest(array){
return Math.min.apply(Math, array);
}
function largest(array){
return Math.max.apply(Math, array);
}
console.log(smallest([0, 1, 2, 3]) == 0); // true
console.log(largest([0, 1, 2, 3]) == 3); // true
apply()메서드를 사용하여 전달된 배열을 가변인자 목록으로 전달한다.
위와 같은 행위는 Math.min(0,1,2,3); 과 기능적으로 동일하게 실행된다.
함수 오버로딩
모든 함수는 암묵적으로 내장된 arguments 매개변수가 전달된다.
arguments를 이용해서 효과적으로 함수 오버로딩을 구현해보자.
인자를 찾아내고 순회하기(가변인자 활용하기)
자바스크립트에서는 전달된 인자의 수와 유형에 따라 동작방식이 변경되는 단일 함수를 이용하여 함수를 오버로드한다.
// 가변인자 목록 순회하기
function merge(root){
for(var i=1; i<arguments.length; i++){
for(var key in arguments[i]){
root[key] = arguments[i][key];
}
}
return root;
}
var merged = merge(
{name : "corn"},
{city : "Incheon"}
);
console.log(merged.name == "corn");
console.log(merged.city == "Incheon");
여기서 함수의 시그니처에 매개변수가 단 하나만 선언된 것을 볼 수 있다. 자바스크립트 함수는 정의된 매개변수와 동일한 수의 인자를 전달하도록 강제하지 않는다.
그렇다면 첫 번째 인자는 root를 이용하여 얻을 수 있지만, 전달된 인자가 더 있는 경우에는 어떻게 접근할 수 있을까? arguments 매개변수는 전달된 인자를 모두 갖고 있는 컬렉션을 참조한다.
우리가 하려는 것은 두 번째부터 n번째로 전달된 객체의 프로퍼티를 첫번째 인자인 root에 통합하는 것이다.
우리는 이제 어떤 값이 전달될지 미리 알 수 없는 상황이라 하더라도 유연하게 동작하는 함수를 만들기 위해서 함수에 전달된 인자를 검사하는데 arguments 컬렉션을 활용할 수 있다.
함수의 오버로딩에 대한 접근방법
오버로딩은 전달된 인자에 따라 함수의 동작이 달라지게 하는 기법을 말한다.
함수의 length 프로퍼티
모든함수는 length라는 프로퍼티를 갖는다. length는 이름을 가진 매개변수(named parameter)의 수가 저장되어 있다.
length프로퍼티를 통해 이름을 지닌 매개변수의 수를 알 수 있음
arguments.length프로퍼티를 통해 호출시에 전달되는 인자의 수를 알 수 있음
인자의 개수를 이용한 함수 오버로딩
var corn = {};
addMethod(corn, 'whatever', function(){do something!});
addMethod(corn, 'whatever', function(a){do something!});
addMethod(corn, 'whatever', function(a, b){do something!});
// 객체를 만든 다음 같은 이름을 이용해서 메서드를 추가하는 방법을 생각해보자.
메서드 오버로딩을 처리하는 addMethod()함수
function addMethod(object, name, fn){
var old = object[name];
object[name] = function(){
if(fn.length == arguments.length)
return fn.apply(this, arguments);
else if(typeof old == 'function')
return old.apply(this, arguments);
}
}
함수인지 확인하기
function corn(){}
console.log(typeof corn == "function")
typeof를 사용하여 어떤 값이 함수인지 여부를 판별하는 전형적인 방법인데, 이 것에는 cross-browser이슈가 존재한다.
브라우저별로 정확히 작동하지 않기 때문이다.(파이어폭스는 HTML의
'프로그래밍 노트 > JAVASCRIPT' 카테고리의 다른 글
[Javascript] 객체지향과 프로토타입_2 (0) | 2019.01.14 |
---|---|
[Javascript] 객체지향과 프로토타입_1 (0) | 2019.01.10 |
[Javascript] 1종객체(함수) 가지고 놀기_1 (0) | 2018.12.20 |
[Javascript] callee 프로퍼티 (0) | 2018.12.20 |
[Javascript] 익명함수 (0) | 2018.12.17 |