요즘 열심히 jQuery사용해보고 있는데 생각했던 것과 다르게 동작하는 것들을 정리하려고 한다.

오늘 발견한거 $.map[링크], map[링크]의 콜백의 인자 순서와 this, 반환 값이 다르다. 

// $.map
$.map(["a","b"],function(v,i){
 // v = value
 // i = index
 this;//window
 return v+"-";
});
// 반환 값 - Array

// map
$(".some").map(function(i,v){
 // i = index
 // v = value
 this;// v
 return v+"-";
});

// 반환 값 - jQuery // native map ["a","b"].map(function(v,i){ // v = value // i = index this;// window return v+"-"; }); // 반환 값 - Array

jQuery에서는  $.map은 native[링크]처럼 map은 좀 다르게 만들었다. 근데 $.map보다는 map이 native와 비슷한 구조라 헷갈린다.

아마도 map이 만들어지고 나서 $.map을 만들어진것 같다. 이후에 map이 native로 추가된 후 map의 사용법을 가져갈까? 표준 api의 사용법을 가져갈까? 고민하다 $.xx의 함수들은 표준 방법을 선택한 듯.

이런건 라이브러리를 만들면서 항상 고민되는 부분이다. 가장 깔끔한건 모두 표준과 같은 방법으로 맞추는건데 이게 쉬운 일인가? -_-;

map이면 굉장히 많이 쓰는 메서드인데 기존의 파라메터의 순서를 바꾸면 헬게이트 열림.

결국엔 기본 map은 수정할 수 없고, $.map을 map과 똑같이 하는 방법, native처럼 하는 방법 두 가지인데 사실 나였으면 지금의 jQuery방식보다는 $.map을 map처럼 바꿀 것 같다. 혹은 $.map을 지원하지 않거나.

지금의 방식은 모든 사람이 혼란스럽지만, $.map과 map의 사용법이 같다면, native에 map이 있는지 모르고 jQuery만 사용하는 사람한데는 혼란스럽지않다.

사실 그보다는 아예 $.map을 지원하지 않는 방법을 선호한다.





Posted by 전용우
,

최근(?) 자바스크립트에서는 모듈 패턴(Module Pattern)을 많이 사용한다.

이렇게 많이 사용하는 이유는 개인적으로 AMD의 영향이 크지 않을까 생각한다. (AMD의 좀 안좋은 인식이 있는데 이건 나중에 시간이 되면 쓰도록 하고....)

뭐.. 어쨌건 모듈 패턴을 사용하는 이유야 다양하겠지만 대부분은 지금의 자바스크립트에서 지원하지 않는 private 속성을 사용하기 위함이 큰 것 같다.(ECMA6에서는 뭐가 있는것 같은데..)

나는 사실 모듈 패턴을 선호하지 않는 편이다. 그 이유 중 하나가 코드 리딩이 힘들다.

왜냐하면 모듈 패턴은 함수로 감싼 형식이라 구현부를 볼 때 함수의 파라메터가 있다면 제일 마지막 부분을 확인해야 알 수 있고 클로져를 생각보다 많이 사용해 코드 리딩도 좀 힘들다. 그래서 난 개인적으로 모듈 패턴을 사용할 때는 파라메터를 넣지 않기를 선호하며 클로져도 적게 쓰려고 한다.

그리고 모듈 패턴을 쓰면 private의 사용이 많아지고 private이 많아질 수록 테스트는 만들기 힘들어진다. 물론, private를 테스트하기 힘든건 모듈 패턴의 문제는 아니다.

이런 경우 대체적으로 private함수는 직접 테스트하기 보다는 private함수를 사용하는 public함수를 테스트한다.

나도 보통은 그렇게 하는데 한편으론 맘에 안들때도 있다.

예를 들면 아래의 코드형식이다.

(function(){
    var global = this;
    function Stub(vName, sType){
        this.stubMethod = new StubMethod();
    }
    Stub.prototype.with_param = function(){
        return this.stubMethod;
    }

    //private
    function StubMethod(iStub){
    }
    StubMethod.prototype.and_return = function(vReturn){
    }

    global.stub = global.Stub = Stub;
})();

위에 코드를 보면 StubMethod는 외부에서 생성해서 사용하지 않기 때문에 외부에 노출하지 않는다.

그리고 with_param의 반환 값이 StubMethod인지 테스트해야 하는 코드를 아래와 같이 작성하려고 한다.

test("with_param의 반환 값은 StubMethod 인스턴스여야 한다.",function(){
    //Given
    var stubInstance = stub("Stub");
    //When
    var stubMethod = stubInstance.with_param();
    //Then
    ok(stubMethod instanceof StubMethod);
 });

근데 여기서 StubMethod는 외부에 노출하지 않았기 때문에 위와 같은 테스트가 불가능하다.

그래서 테스트하는 방법을 고민해봤는데 몇 가지가 떠올랐다.

첫 번째. 반환 값을 가지고 add_return을 사용하여 테스트한다.(간접적으로)

두 번째.  반환 값에서 add_return메서드가 있는지 확인하는 테스트를 작성해야 한다(덕타이핑과 같이)

세 번째. 키워드를 넘겨서 테스트 중이면 외부에서도 StubMethod를 접근할 수 있게 한다. (이건 좀 구린것 같다.)

처음 고민한건 add_return 함수의 기능을 테스트하면 StubMethod인지 동시에 테스트되는 방법이다. 물론 간접적으로 테스트 되지만 반환 값이 StubMethod인지 테스트하는 부분이 코드로 표현되지 않아서 좀 별루라고 생각했다.

이것 저것 고민하다가 결국엔 덕타이핑으로 판단했지만 여전히 찜찜함은 남는다.

test("with_param은 반환 값이 StubMethod 인스턴스여야 한다.",function(){
    //Given
    var stubInstance = stub("Stub");
    //When
    var stubMethod = stubInstance.with_param();
    //Then
    // ok(stubMethod instanceof StubMethod);
    // StubMethod는 private으로 접근할 수 없어 덕타이핑으로 판단한다.
    equal(typeof stubMethod.and_return,"function");
});


이와 관련한 질문도 많고 답변도 봤는데 나의 고민을 해결해주는 글은 없었다. 그리고 유사한 패턴이 jQuery의 Deferred, Promise인 것 같아서 코드와 테스트 케이스를 보니 위에 경우랑은 좀 차이가 있었다.

결론은 위와 같이 했지만 이런 경우는 어떻게 처리해야 할지 아직 고민이 된다.


ps. 여전히 고민인 건 정말 private로 만들어야만 했는가? 그냥 public이면 되는거 아닌가? 외부에 노출시켜 발생하는 문제에 비해 테스트의 가치가 큰게 아닌가? 등 많은 고민이 되는데 잘 모르겠다.


ps. 정말 오랫만에 블로그를 썼다. 한동안 바쁘다는 이유로 안썼는데 이젠 조금씩 써보려고 하는데 얼마나 갈지는 잘 모르겠다. ㅎㅎ

Posted by 전용우
,
지난 화요일날 webtech의 css세미나를 다녀온적이 있다.

내용도 좋았고 나름 재미있는 시간이였다.

거기서 각종팁들을 알져 줬는데 그중에 하나가 각각 짜른 이미지가 아니라
통이미지로 올려서 이미지들을 숨기는 방법을 알려줬다.

강사(임종혁님)가 말하길 이미지의 용량보다 이미지갯수가 페이지를 로딩하는데 더 큰 문제라고 하시면서 위와 같은 팁을 알려줬는데 바로 오늘 에이시안에 해당들이 올라왔다.

한번 확인해 보시길.^^

Posted by 전용우
,