골때리는 자바스크립트 외전 3탄 – 인자를 품은 foreach, 인품포

해품달 흉내내다 재미없다고 싱고하진 않겠지..

오랜만에 자스 실무를 경험하면서 나온 팁을 골자외 3탄에서 소개해 드립니다.

JSON Object 의 키를 루프돌면서 처리할때 for in 문을 많이 쓰실 겁니다.

var a={a:’a’,b:’b’};

for(var x in a){

    window.status+=x+’ : ‘+a[x];

}

자.. 근데 이런 상황에 대한 대처를 해야 합니다.

여러분이 동적 클래스 함수를 만들었습니다.

각 지정된 함수를 호출 시 호출된 함수 이름으로 된 값을 저장해야 합니다.

예를 들면 아래와 같습니다.

function keyStore(){

    var that=this;

    this.fn={prepare:0,start:0,finish:0,result:0};

    for(var name in fn) this[name]=function(fn){

        that.fn[name]=fn;

    };

}

그런 다음, keyStore 동적 클래스를 선언하고, 각각 fn 의 키 함수를 실행해 보세요.

var key=new keySotre();

key.prepare(function(){ alert(‘prepare’); });

key.start(function(){ alert(‘start’); });

key.finish(function(){ alert(‘finish’); });

key.result(function(){ alert(‘result’); });

그리고 console.log(key.fn); 쳐보세요.

우리가 원하는 결과는 이렇습니다.

{

    prepare:function(){ alert(‘prepare’); },

    start:function(){ alert(‘start’); },

    finish:function(){ alert(‘finish’); },

    result:function(){ alert(‘result’); }

}

하지만 현실은 아래와 같은 결과가 나올 것입니다.

{

    prepare:0,

    start:0,

    finish:0,

    result:function(){ alert(‘result’); }

}

당최 왜그럴까요? 그것은 바로 for in 문의 name에 문제가 있습니다.

지역 변수의 성질을 알면 원인을 충분히 알 것입니다. (프로그래밍 구조나 컴파일러 배웠다면 떡이겠죠.)

모르는 분을 위해서 간단하게 설명해 드리겠습니다.

name은 변수 입니다. 인자가 아니죠. name 이란 주소는 고정되어 있습니다.

그상태에서 인라인 함수를 등록했습니다. name은 상위 지역 변수로 고정되어 있습니다.

for 문이 돌리는 동안 name 변수는 유효했지만, 끝나면서 name 변수는 마지막으로 기록하고 소멸되었습니다.

인라인 함수들은 소멸된 변수를 계속 참조하지만, 모두 마지막에 기록한 name=’result’ 로 알게 되는 것이죠.

그렇다면 어떻게 이런 난관을 해결할 수 있을까요? 간단합니다.

소멸된 변수를 직접 참조하지 말고 인라인 함수를 만들어 인자로 받으세요. 그럼 해결됩니다.

function keyStore(){

    var that=this;

    this.fn={prepare:0,start:0,finish:0,result:0};

    for(var name in fn) (function(nm){

        that[nm]=function(fn){

            that.fn[nm]=fn;

        };

    })(name);

}

그럼 각각 name을 익명 함수로 호출하여 각각 key를 담게 됩니다. 그러면 원하는 결과가 나옵니다.

다시한번 절차를 밟아보시고.

var key=new keySotre();

key.prepare(function(){ alert(‘prepare’); });

key.start(function(){ alert(‘start’); });

key.finish(function(){ alert(‘finish’); });

key.result(function(){ alert(‘result’); });

디버그 콘솔에 console.log(key.fn); 쳐서 아래와 같이 나오면 성공입니다.

{

    prepare:function(){ alert(‘prepare’); },

    start:function(){ alert(‘start’); },

    finish:function(){ alert(‘finish’); },

    result:function(){ alert(‘result’); }

}

자스가 이렇게 유연하다 보니 프로그래밍 기초가 원인이 되는 여러가지 난관에 부딪힐 수 있습니다. 이 점에 유의해가면서 사용해야 한다는 걸 알려주는 교훈을 얻고 이 강좌를 쿨하게 끝내겠습니다.

답글 남기기

Your email address will not be published / Required fields are marked *