dovelet 문제를 이용한 call, apply, bind

어제 가입하고 첫 글이라서 그런지 약간 긴장이 되네요.

웹 개발자를 목표로 하고 있지만 갈팡질팡하다가 javascript로 주언어로 잡기로 결정한지 최근인데

어디서 부터 시작해야 할까 하다가 제가 C 할때 언어 연습할겸 했던 프로그램 문제풀이(아직 알고리즘이라 하기도 민망해서)부터 하기로 했습니다.

다른 사람들은 왜 그런거나 하느냐고 핀잔주기도 하지만 문제의 해결과 구현을 프로그래밍 언어로 한다는 것은

단순히 문제 풀이를 떠나서 그 언어에 대해 깊이 파고들 수 있는 수단이라 생각합니다.

제가 오늘 푼 문제는 dovelet.com 에 있는 30계단의 1단계의 spot-of-light라는 문제입니다.
http://119.201.123.184/30stair/spot/spot.php?pname=spot

프로젝터와 벽까지의 거리를 d라고 하고 프로젝터가 비추는 면적의 반지름을 r이라 할때

거리 d를 주어지고 r의 a%만큼 변화시키고 싶을 때 d가 얼만큼 변해야 하는가를 구하는 문제입니다. (비추는 각은 항상 같다고 간주합니다.)

문제 자체는 단순합니다. r = tanX * d 인데 r을 변화시키고 싶으면 r *(1 + a) = tanX * d *(1 + a) 과 같아, r 과 d가 같은 비율만큼 증감한 다는 것을 알 수 있습니다.(tanX는 항상 같다고 가정합니다.)

call -v
이 문제를 call 버전으로 풀었습니다.

var input = {
    d:28.5,
    rChange:-0.25
};

getDistance.call(input);

function getDistance (){
    var changeTo = this.d*(1 - this.rChange);
    var dChange = (changeTo - this.d).toFixed(3); //소수점 세자리에서 반올림 합니다.
    console.log('distance change : %d', dChange);
}

call을 통해 getDistance에 input객체를 넣으면 getDistance 객체(함수)에 input의 lexical env에 등록이 되어지고

그롤통해 this를 구현 할 수있게 됩니다. 사실 굳이 디스를 안해도 input이 global로 들어가 있는지라 안해도 되지만

call을 사용해 봤다는데 의미를 두어야 할 것 같습니다.

이래저래 편리한 메서드라는 생각이 들었습니다. 실행시키기 위해 input의 형태를 고정시킬 필요가 있어 보이긴 합니다만

굳이 상속을 할 필요도 없이, 필요할 때 객체를 내부 실행환경(execution context)에 추가 시킬 수 있다는 것은 놀라운 것 같습니다.

어디에 써야 할지는 아직 잘 모르겠습니다. 지금은 겨우 간단한 알고리즘 쪼가리에 사용해 보는 것이 다이지만 분명

앞으로 유용할 것이라 생각이 들었습니다.

(아직 잘 모르겠는 것은, 함수 객체가 다른 객체를 바인드 한 것인지 input에 함수 객체가 call 된 것인지 잘 모르겠습니다.

계란이 먼저냐 닭이 먼저냐는 논쟁으로 보이긴 합니다만 공부하다보면 답이 나오지 않을까 합니다. )

apply
apply 버전으로 해봤습니다만, 함수객체의 인자값을 배열로 한방에 넘겨 줄 수 있다는 점 외에는

그다지 call과 달라보이지 않았습니다.

var input = {
    d:28.5
};
var rChange = [-0.25];

getDistance.apply(input, rChange);

function getDistance (rChange){
    var changeTo = this.d*(1 - rChange);
    var dChange = (changeTo - this.d).toFixed(3);
    console.log('distance change : %d', dChange);
}

bind
바인드는 javascript의 특성을 보여주는 매우 흥미로운 메서드라는 생각이 들었습니다.

var input1 = 
{
    d:28.5,
    rChange:-0.25
};

var binded = getDistance.bind(input1);

binded();

function getDistance (){
    var changeTo = this.d*(1 - this.rChange);
    var dChange = (changeTo - this.d).toFixed(3);
    console.log('distance change : %d', dChange);
}

apply나 call은 일회용 이라는 느낌이 강합니다만 bind는 재활용이 가능하다는 느낌이 훨씬 풍깁니다. 그 이유는

apply나 call은 실행 시에 함수객체에 필요한 인수까지 한꺼번에 입력을 해주어야 실행이 됩니다만

bind를 통해 input객체를 실행환경에 등록시킨 함수객체를 반환하여 차후에 함수의 인자값을 입력 할 수 있다는 점에서 그렇게 느꼈습니다.

글을쓰면서 아직 많이 부족하다는 생각이 듭니다. 메서드가 어떻게 돌아가는지는 이런 간단한 연습을 통해 대충이라도

알 수 있지만 어떻게 사용 해야 할지는 전혀 머리에 떠오르지 않는 것을 보면 말입니다.

앞으로 정진해야겠습니다.

P.S 혹시 잘못된 정보를 작성한 부분이 있다면 죄송합니다 ㅠㅠ