Javascript apply

[Javascript] apply


apply 사용법

apply는 javascript에서 함수를 호출하는 방법 중 하나이다.

1
2
3
4
5
6
7
8
9
function test() {
		// body
}
test.apply(null);

function test2(arg) {
		// body
}
test2.apply(null, [1]);


apply는 언제 사용하는가?

apply로 함수를 호출하면 함수 내에서 사용되는 this를 조작할 수 있다.

우선 this는 무엇인가? javascript에서 this는

  1. this가 호출된 함수가 객체 내부 함수일 경우 자기 자신의 인스턴스를 의미한다.
  2. 그렇지 않으면 window를 의미한다.

즉, this는 JS의 렉시컬 스코프에 의해 의미가 달라진다. (window는 JS의 최상위 객체. JS 코드의 모든 객체, 전역변수, 전역함수 등은 window의 속성이다.)

apply 사용 방법을 설명한 위 코드에서 첫 번째 인자는 null이다. 이 자리에 다른 객체 값을 넘겨주면, 함수 내에서는 인자로 넘겨준 객체를 this로 인식한다.

간단한 예를 들어 이 방식이 어느 상황에서 쓰일 수 있을지 생각해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function sum() {
    let _sum=0;
    for(name in this) {
        _sum += this[name];
    }
    return _sum;
}

function test() {
    let obj1 = {v1:1, v2:2, v3:3, v4:4};
    let obj2 = {val1:100, val2:120, val3:140, val4:2};
    
    console.log(sum.apply(obj1));
    console.log(sum.apply(obj2));
}

test();

// 출력 결과
10
362

위 코드는 test라는 함수에서 생성된 객체에 담긴 값들의 합을 출력하는 예제이다. 만약 apply와 this를 사용하지 않는다면 코드는 어떻게 작성될까?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function sum() {
    let _sum=0;
    for(name in this) {
        _sum += this[name];
    }
    return _sum;
}

function test() {
    let obj1 = {v1:1, v2:2, v3:3, v4:4, sum:sum};
    let obj2 = {val1:100, val2:120, val3:140, val4:2, sum:sum};
    
    console.log(obj1.sum());
    console.log(obj2.sum()));
}

test();

// 출력 결과
10function sum() {
        let _sum=0;
        for(name in this) {
            _sum += this[name];
        }
        return _sum;
    }
362function sum() {
        let _sum=0;
        for(name in this) {
            _sum += this[name];
        }
        return _sum;
    }

apply를 사용하지 않고 함수 내에서 this를 사용하기 위해선 객체 내 함수 (=메서드) 를 정의하는 방법을 사용해야 한다. 이에 obj1과 obj2에 sum 함수를 추가했다.

이 코드의 출력 결과를 보면 의도한 것과는 다른 결과가 나왔다. sum 메서드 역시 this의 일부분이므로 for문에 포함되어 함수 내용까지 출력된 것이다.

의도한 결과값을 내기 위해선 sum 함수를 아래와 같이 수정해야 한다.

1
2
3
4
5
6
7
8
function sum() {
    let _sum=0;
    for(name in this) {
        if(typeof this[name] !== 'function')
        _sum += this[name];
    }
    return _sum;
}

이렇듯 this를 사용할 때 apply로 함수를 호출하는 코드는 그렇지 않은 코드보다 더 간결하다. this를 사용하는 모든 상황에서 apply를 사용하는 것이 낫다고 장담할 수는 없지만, apply를 사용하면 더 간결하고 유동적인 코드가 나올 수도 있음을 알고 넘어가자.

apply의 강점인 유동적인 사용은 객체와 this를 공부하면서 알 수 있다. 이와 관련하여 이 포스트도 함께 읽어보면 도움이 될 것 같다.

참고로 apply 외에 call()도 apply와 동일한 기능을 한다. 다만 인자를 넘겨주는 방식에 차이가 있다.

apply는 인자를 배열형으로 넘겨줌. 함수명.apply(null, [1,2]); call는 인자를 일반 함수와 동일하게 넘겨줌. 함수명.call(null, 1, 2);

0%