파이어준님의 블로그에 엄청나게 좋은 글이 있었는데 저작권이 CC라서 보관도 할겸 가져왔다.
바로 프로토타입을 효과적으로 활용하는 방법에 관한 건데.
초반부를 보면서는 "음 나도 좀 쓰고있군" 했는데 update나 invoke, Ajax.Request 에서 parameters 쓰기 등에서 좌절. Template은 존재 여부도 모르고 있었다. 알게되었으니 유용하게 사용해야겠다.

//바르지 못한 방법:
document.getElementById("foo ")
//적당한 방법: 놀랍게도 어떤 사람들은 이것에 대해 잘 모른다.
$("foo ")

//바르지 못한 방법:
var woot = document.getElementById("bar").value
var woot = $("bar").value
//적당한 방법: 폼 값의 편리하고 빠른 호출
var woot = $F("bar")

//바르지 못한 방법:
$('footer').style.height = '100px';
$('footer').style.background = '#ffc';    
//적당한 방법: 모든 브라우저가 W3C의 권고를 따르고 있지 않다.
$('footer').setStyle({
    height: '100px',
    background: '#ffc'
})

//바르지 못한 방법:
$('coolestWidgetEver').innerHTML = 'some nifty content'
//적당한 방법:
$('coolestWidgetEver').update('some nifty content')
// 아래와 같은 문법 구사가 가능해 지므로
$('coolestWidgetEver').update('some nifty content').addClassName('highlight').next().hide()

//바르지 못한 방법:
new Ajax.Request('ninja.php?weapon1=foo&weapon2=bar')
//적당한 방법: 보기 좋으며 보다 나은 파라메터 구조 사용
new Ajax.Request('ninja.php', {
    parameters: {
        weapon1: 'foo',
        weapon2: 'bar'
    }
})

//바르지 못한 방법:
new Ajax.Request('blah.php', {
    method: 'POST',
    asynchronous: true,
    contentType: 'application/x-www-form-urlencoded',
    encoding: 'UTF-8',
})
//적당한 방법: 기본옵션은 생략하라!
new Ajax.Request('blah.php')

//바르지 못한 방법:
Event.observe('myContainer', 'click', doSomeMagic)
//적당한 방법: 논쟁의 여지가 있지만 객체지향적이다!
$('myContainer').observe('click', doSomeMagic)

//바르지 못한 방법:
$$('div.hidden').each(function(el){
    el.show();
})
//적당한 방법: 슬프게도 이 사용법을 아는 사람들이 많지 않다는 사실.
$$('div.hidden').invoke('show')

//바르지 못한 방법:
$$('div.collapsed').each(function(el){
    el.observe('click', expand);
})
//적당한 방법: invoke를 이용한 이벤트 핸들링, 졸라 쉽다!
$$('div.collapsed').invoke('observe', 'click', expand)

//바르지 못한 방법:
$$('input.date').invoke('observe', 'focus', onFocus);
$$('input.date').invoke('observe', 'blur', onBlur);
//적당한 방법: $$는 오버해드가 크기 때문에 invoke를 사용하면 $$를 여러번 사용할 필요도 없다.
$$('input.date').invoke('observe', 'focus', onFocus).invoke('observe', 'blur', onBlur)

//바르지 못한 방법:
$('productTable').innerHTML =
    $('productTable').innerHTML +
    '<tr><td>' + productId + ' '
    + productName + '</td></tr><tr><td>'
    + productId + ' ' + productPrice +
    '</td></tr>'
//적당한 방법: Template 클래스는 정말 쓸만한 DOM 솔루션이다. 하지만 잘 사용되고 있지 않는 것 같다.
var rowTemplate = new Template('<tr><td>#{id} #{name}</td></tr><tr><td>#{id} #{price}</td></tr>');
$('productTable').insert(
    rowTemplate.evaluate({
        id: productId,
        name: productName,
        price: productPrice
    }))
)

invoke에 인자로 넘어가는 function 이름이 string길래 순간 eval인가? 라는 말도안되는 생각에 설마하면서 소스를 뒤져보니 다행히 eval은 아니었고(당연하지!) invoke의 소스는 아래와 같이 되어있었다.
invoke: function(method) {
    var args = $A(arguments).slice(1);
    return this.map(function(value) {
        return value[method].apply(value, args);
    });
}

function명과 추가적인 인자들을 넘겨주면 해당 function에 자신과 인자들을 넣어서 실행하는 것 같다.
eval 대신에 그냥 맵처럼 function을 호출할 수 있다는건 조금 신기하기도 했고.

프로토타입은 쓰면 쓸수록 맘에 든다. 이 포스팅이 좀더 잘 활용할 수 있는 계기가 되길 바란다.


License
달리 정하지 않는 한, 이 저작물 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Except where otherwise noted, this content is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Korea License

+ Recent posts