call() apply()

call()

call 함수는 자주 쓰이지만 호출하는 기능 정도로만 이해하고 있던터라,
이번에 자세히 알아보려고 합니다.

call 함수가 하는 기능은 크게 두가지 입니다.

  • this를 변경
  • 메소드를 실행
func.call(this,arg1,arg2...)
// this - 호출에 제공되는 this의 값
// arg1,arg2... - 호출에 전달되는 매개변수

생성자 연결에 call 사용

<script>
    function Product(name, price) {
        this.name = name;
        this.price = price;

        if (price < 0) {
            throw RangeError('Error');
        }
    }
</script>

Product 생성자는 이름과 가격을 매개변수로 정의 합니다.

<script>
    function Food(name, price) {
        Product.call(this, name, price);
        this.category = 'food';
    }

    function Toy(name, price) {
        Product.call(this, name, price);
        this.category = 'toy';
    }

    var cheese = new Food('feta', 5);
    var fun = new Toy('robot', 40);
</script>

Food와 Tody 함수는 Product 함수를 호출합니다.
매개변수도 전달합니다.
Food 객체에서 Product 객체를 복사하여 사용합니다.
Food 객체는 아래와 같은 형태를 가지고 있게 됩니다.

Food
    category : "food",
    name : "feta",
    price: 5

익명 함수에서 call 사용

<script>
    var animals = [
        { species: 'Lion', name: 'King' },
        { species: 'Whale', name: 'Fail' }
    ];

    for (var i = 0; i < animals.length; i++) {
        (function(i) {
            this.print = function() {
                console.log('#' + i + ' ' + this.species
                    + ': ' + this.name);
            }
            this.print();
        }).call(animals[i], i);
    }
</script>

배열 내 객체를 순회하며 익명 함수가 실행됩니다.
위 예제와 마찬가지로 animals[i] 객체가 익명 함수를 복사해서 사용했습니다.

함수 호출을 위한 call 사용

<script>
    function greet() {
        var reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
        console.log(reply);
    }

    var obj = {
        animal: 'cats', sleepDuration: '12 and 16 hours'
    };
</script>

this의 값이 obj 객체로 바인딩 됩니다.

매개변수없이 call 사용

<script>
    var sData = 'Wisen';
    function display(){
        console.log('sData value is %s ', this.sData);
    }

    display.call();  // sData value is Wisen
</script>

인수를 전달하지 않고 호출하면 this는 전역 객체에 바인딩 됩니다.

apply()

apply는 call과 사용방법은 동일하나 전달 인자를 한개만 전달합니다.

func.apply(this, [argsArray])
// this - func를 호출하는데 제공될 this의 값
// argsArray - func에 사용되는 유사 배열 객체

배열과 배열을 붙이기 위해 apply 사용

배열 메소드중 하나인 push를 사용하면 배열 내에 요소를 추가할 수 있습니다. 하지만 배열과 배열을 붙이기 위해 push를 사용하면 배열 내 배열로 사용되어 버립니다.
이를 해결하기 위해 apply를 활용합니다.
배열 함수를 사용할 수 없는 유사 배열 객체에 배열 함수를 사용하기 위해 빌려오는 역할을 합니다.

<script>
    var array = ['a', 'b'];
    var elements = [0, 1, 2];
    array.push.apply(array, elements);
    console.info(array); // ["a", "b", 0, 1, 2]
</script>

더 이해를 쉽게 하기 위한 예제입니다.

<script>
    var person = {
        fullName: function(city, country) {
            return this.firstName + " " + this.lastName + "," + city + "," + country;
        }
    }
    var person1 = {
      firstName:"John",
      lastName: "Doe"
    }
    person.fullName.apply(person1, ["Oslo", "Norway"]);
</script>

call과는 다르게 매개변수를 배열 객체로 넘겼습니다.

apply와 내장함수 사용

<script>
    var numbers = [5, 6, 2, 3, 7];
    var max = Math.max.apply(null, numbers); 
</script>