TIL-JavaScript(argument,apply)

연시아·2022년 6월 1일
0

TIL

목록 보기
32/51
post-thumbnail

22.06.01

🍌 argument 소개

함수에는 arguments 라는 변수에 담긴 숨겨진 유사배열이 있습니다. 아래의 예제에는 함수를 호출할 때 입력한 인자가 담겨있습니다. 결과는 10입니다.

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript">
function sum(){
    var i, _sum = 0;    
    for(i = 0; i < arguments.length; i++){
        document.write(i+' : '+arguments[i]+'<br />');
        _sum0 += arguments[i];
    }   
    return _sum;
}
document.write('result : ' + sum(1,2,3,4));
</script>
</body>
</html>

함수 sum은 인자로 전달된 값을 모두 더해서 리턴하는 함수입니다. 그런데 1행처럼 함수 sum은 인자에 대한 정의하가 없습니다. 하지만 마지막 라인에서는 4개의 인자를 함수 sum으로 전달하고 있습니다. 함수의 정의부분에서 인자에 대한 구현이 없음에도 인자를 전달할 수 있는 것은 왜 그런걸까요? 그것은 arguments 라는 특수한 배열이 있기 때문입니다.
arguments는 함수안에서 사용할 수 있도록 그 이름이나 특성이 약속되어 있는 일종의 배열입니다. arguments[0]은 함수로 전달된 첫번째 인자를 알아낼 수 있습니다. 또 arguments.length를 이용해서 함수로 전달된 인자의 개수를 알아낼 수도 있습니다. 이러한 특성에 반복문을 결합하면 함수로 전달된 인자의 값을 순차적으로 가져올 수 있습니다. 그 값을 더해서 리턴하면 인자로 전달된 값에 대한 총합을 구하는 함수를 만들 수 있습니다.
arguments는 사실 배열이 아닙니다. 실제로는 arguments 객체의 인스턴스입니다.

🥝 function.length

매개변수와 관련된 두가지 수가 있습니다. 하나는 함수.length이고, 다른 하나는 arguments.length 입니다. arguments.length는 함수로 전달 된 실제 인자의 수를 의미하고, 함수.length는 함수에 정의된 인자의 수를 의미합니다.

function zero(){
    console.log(
        'zero.length', zero.length,
        'arguments', arguments.length
    );
}
function one(arg1){
    console.log(
        'one.length', one.length,
        'arguments', arguments.length
    );
}
function two(arg1, arg2){
    console.log(
        'two.length', two.length,
        'arguments', arguments.length
    );
 }
zero(); // zero.length 0 arguments 0 
one('val1', 'val2');  // one.length 1 arguments 2 
two('val1');  // two.length 2 arguments 1

zero.length, one.length...는 파라미터의 개수이고, arguments.length는 인자의 개수입니다.
따라서, 아래의 그림과 같이 결과가 출력되는 것을 볼 수가 있습니다.

🍈 apply 소개

함수를 호출하는 가장 기본적인 방법은

function func(){
}
func();

javascript는 함수를 호출하는 특별한 방법을 제공합니다. 위의 예제에서는 함수 func는 function이라는 객체의 인스턴스입니다. 따라서 func는 객체 function이 가지고 있는 메소드들을 상속하고 있습니다. function.apply과 function.call 이 메소들을 이용해서 아래의 예제처럼 함수를 호출해봤습니다. 결과는 3이라는 것을 볼 수 있습니다.

function sum(arg1, arg2){
    return arg1+arg2;
}
alert(sum.apply(null, [1,2]))

함수 sum은 function 객체의 인스턴스입니다. 그렇기 때문에 객체 function의 메소드 apply를 호출 할 수 있습니다. apply 메소드는 두 개의 인자를 가질 수 있는데, 첫 번째 인자는 함수(sum)가 실행될 맥락입니다. 두 번째 인자는 배열인데, 이 배열의 담겨있는 원소가 함수(sum)의 인자로 순차적으로 대입됩니다.

🍍 apply 사용

function sum(){
    var _sum = 0;
    for(name in this){
     _sum += this[name];
    }
    return _sum;
}
o1 = {val1:1, val2:2, val3:3, sum:sum}
o2 = {v1:10, v2:50, v3:100, v4:25, sum:sum}
alert(o1.sum());
alert(o2.sum());

o1는 3개의 속성을 가지고 있습니다. 각각의 이름은 val1, val2, val3입니다. o2는 4개의 속성을 가지고 있고 o1과는 다른 속성 이름을 가지고 있고 속성의 수도 다릅니다. 그 다음엔 함수 sum을 만들었습니다. 이 함수는 객체의 속성을 열거할 때 사용하는 for in문을 이용해서 객체 자신(this)의 값을 열거한 후에 각 속성의 값을 지역변수 _sum에 저장한 후에 이를 리턴하고 있습니다. 객체 function의 메소는 apply의 첫번 째 인자는 함수가 실행될 맥락입니다. sum.apply(o1)은 함수 sum을 객체 o1의 메소드로 만들고 sum을 호출한 후에 sum을 삭제합니다.
우선 위의 예제처럼 코드를 작성하면 경고창에 이렇게 출력이 되는 걸 볼 수 있습니다.

수의 내용까지 같이 포함해서 나오는 걸 볼 수 있습니다. 왜 이렇게 결과물이 나왔냐면 o1과 o2의 sum이라는 속성을 추가 했기때문에 for문의 this를 열거하는 과정에서 자연스럽게 sum이라는 함수도 더하고 있기 때문에 이렇게 출력이 된 것을 볼 수 있습니다.
이것을 방지할라면 ' if(typeof this[name] !== 'function')' 조건문을 사용하면 되는데 이렇게 조건문을 넣게 되면

function sum(){
    var _sum = 0;
    for(name in this){
      if(typeof this[name] !== 'function')
        _sum += this[name];
    }
    return _sum;
}
o1 = {val1:1, val2:2, val3:3, sum:sum}
o2 = {v1:10, v2:50, v3:100, v4:25, sum:sum}
alert(o1.sum());
alert(o2.sum());

이렇게 코드를 작성하면 결과는 이렇게 출력이 됩니다.


차례대로 결과가 출력 되는 걸 볼 수가 있습니다.

profile
backend developer

0개의 댓글