이번 포스트에는 함수의 method 인 .call과 .apply 그리고 .bind까지 복습해볼 것이다.

일단 지난번에 복습했듯 .call과 .apply의 차이는 인자를 하나 하나씩 받는 것, 그리고 인자를 배열로 받는 것 그 차이가 있다.
call 과 apply 의 예제를 보자.

function add (x, y){

this.val = x+y;

console.log(this.val)
}

let obj = {val: 0};

add.call(obj, 2, 8); //10

add.apply(obj, [2, 8]); //10

call 과 apply 모두 함수를 실행하지만 인자로 들어가는 것이 다르다.

let arr = [1, 4, 2, 8, 3];

Math.max.apply(null, arr); //8

apply에서 만약에 배열만 받는다면 this 값이 의미가 없을 때는 null을 넣어주면 된다.

.bind는 call 혹은 apply처럼 함수를 실행하지 않고 this 값이 바인딩된 함수를 리턴한다.

let bindit = add.bind(obj, 2, 8);

bindit 을 하면 add함수가 obj라는 this값을 바인딩 해서 함수를 호출한다. 클로저 처럼 호출을 하고 실행은 하지 않는다.

그래서 bindit()을 하면 10이라는 값을 준다. bind는 보통 this의 값을 무엇으로 고정시켜 바인드 하고 싶을 때 사용한다.

function whatisprice (allowance, cost){
this.cost = cost;
this.allowance = allowance;

this.getchange = function () {
return this.allowance - this.cost;
}

this.printchange = function () {
console.log(this.getchange() )
}

};

let water = new whatisprice(50, 20);
water.printchange() //30;

이렇게 예를 들어서 코드를 짜보면 여기서 this 는 whatisprice 라는 class의 instance 인 water이다.

그렇다면 바인딩은 언제 쓰는 것일까?

setTimeout(water.printchange, 5000);

이 코드를 실행한다면 30이 5초 후에 나올 수 있을까? 답은 아니다 이다.

setTimeout이 실행되면 this의 값이 기본적으로 window 객체가 된다.
그러므로 water가 this가 아니기 때문에 없는 함수라고 나온다.

이걸 해결할 때 bind를 이용해 this의 값을 water로 설정해주는 것이다.

setTimeout(water.printchange.bind(water), 5000);

이런 식으로 this의 값을 water로 지정해준다면 문제없이 코드가 돌아간다.

bind로는 커링도 가능하다.

function greeting (name, age) {
return "Hi, my name is " + name + " and I am " + age;
}

let Joshua = greeting.bind(null, "Joshua");

여기서 Joshua는 greeting이라는 함수 자체를 반환한다. 하지만 그 속에는 "Joshua"가 바인드 돼있다.
this의 값을 지정해주지 않기 때문에 bind의 첫번 째 인자는 null이다.

Joshua(18); // "Hi, my name is Joshua and I am 18"을 반환한다.

기억하자! bind는 this의 값을 지정해주기 위해 사용한다는 것.