이미 좀 지난 이야기이긴 하다.
보기는 오래 전에 봤는데 이것에 대해 많은 사람들이 의견이 분분해서 그냥 잊고 있었는데
오늘 YUI Theater — Nicholas Zakas: "Maintainable JavaScript"을 봤는데 중간에 이에 대해
말을 하고 있다. 다시 한번 옛기억을 더듬으며 찾아봤다.

Object.prototype에 대해 찬성파 의견
Object확장을 하므로서 좀 더 편하게 프로그램밍을 할수 있다.
예를들면 object에 each같은 메소드를 만들면 편하게 array나 기타등등에서 편히 사용할수 있다.


Object.prototype에 대해 반대파 의견
자바스크립트의 특징인 오브젝트의 hash-table형식이 잘못된다.
예를 들면 내가 Object에 each라는걸 만들어 버리면 for..in 사용시 내가 생각했던것과 다르게 나타난다.그럼 따로 예외처리를 해야하는데 쉽지않다.

ps.하여간 Maintainable JavaScript을 보니깐 자바스크립트가 점차 대우받는 언어가 되는것 같아 좋네.(영어라 거의 못알아 들었습니다.ㅎㅎ;)

참고글:
Object.prototype is verboten
Object.prototype is erlaubt
Posted by 전용우
,
Prototype에게는 Script.aculo.us가 있다면 jQuery에게는 Interface Elements가 있다.

prototype이 참 편하고 좋았는데 그중에서 script.aculo.us가 있는게 더쓰기 좋았던 이유였습니다. 하지만 이젠 jQuery에게도 Interface Elements 생겼으니 한번 사용해봐야겠습니다.

script.aculo.us와 비교해서 거의 틀린것이 없습니다.특별한것은 별로 없고 거의 다 있는것이고
없더라고 이미 prototype이용해서 유사하게 나온 component들이라 막 끌리진 않습니다.
하지만 jQuery도 한번 살펴볼겸 한번 갈아 타보고 싶네용.

덧.테크노라티가 이번에 리뉴얼할때 jQuery를 사용했다고 하죠?^^;

Posted by 전용우
,

33장.Making a Plugin

대기중(이건 제가 한번 자세히 해보고 포스팅하겠습니당)ㅡㅡ;


34장.Named Routes

routes.rb에서 커스텀 라우터을 사용하여 핼퍼메소드을 이용해 좀 더 쉽게
link를 만드는방법.


routes.rb에서 map.resourse를 이용하여 간단히 만든다음 view에서 핼퍼메소드를 이용.

35장.Custom REST Actions

RESTful 환경만들기
레일즈에서는 좀더 쉽게 rest[각주:1]환경을 지원한다.
routes.rb 에 map.resources :tasks라고 하면 새로운 라우터 7개[각주:2]와 4개의 핼퍼메소드[각주:3]를 사용할수 있게된다.

하지만 이모든것들이 모두 필요한것이 아니다.특정 리소스에대해 특별히 처리하고 싶을때는
:collection=>{액션=>http request}을 사용하면된다.그리고 특별한 액션을 추가하고 싶을경우는 :member=>{액션=>http request}을 사용하면되고 새로운 자원을 만드는 특수한 액션은 :new=>{액션=>http request}로 만들수 있다.

참고로 delete같은경우는 실제로 request를 delete로 보내는것이 아니라 자바스크립트로 전송하기 때문에 자바스크립트가 꺼져있는경우는 작동을 하지 않는다.

참고:레일즈와 함께하는 에자일 웹개발 20장

36장.Subversion on Rails

rails에 svn을 사용하는 방법을 다룹니다.
여기서는 저와 다른 맥의 TextMate을 사용하고 있습니다.
저같은 경우는 aptana를 사용하고 있는데 aptana같은 경우는 일반 이클립스와 동일하게 사용
하시면 되지만 그냥 url업데이트할때 에러가 날겁니다.
Mylar의 버전이 바르지 않다고 나옵니다. 그럴땐 Mylar부분을 헤제한후 사용하면됩니다.
참고글:Aptana + Radrails - how to import a project from SVN ?

37장.Simple Search Form

이번장에서는 모델이 필요없는 폼인경우 작성법을 말하고 있다.
search form같은 경우는 모델이 필요없다.
모델이 필요없는 폼인 경우에는 form_tag를 사용하여 파라메터만 넘긴다.
아래와 같이 사용.
form_tag 컨트롤러_path do
    .....
end
  1. 간단히 말하면 리소스들을 4가지액션(get,put,post,delete)들로 조작하는것 입니다,좀더 자세한 것들은 REST을 확인하기 바랍니다. [본문으로]
  2. index,create,new,show,update,edit,destory [본문으로]
  3. user_path, hash_for_new_user_path, users_url [본문으로]
Posted by 전용우
,

closures

프로그래밍 2007. 5. 17. 18:27
저번에 javajigi에서 발표할때가 있었다.
closure설명을 하다가 질문 중 하나가  "ajax in action에서 closure를 사용하면 메모리가 회수가 안된다.그래서 가능하면 사용하지 말라고 했다. 왜 그러냐?"는 질문이 있었는데.
나의 대답은 "순환관계일경우 회수가 안된다"라고 말했던것으로 생각한다.

그 당시 말 뜻을 잘 전달을 못한것 같아 다시 정리를 해보면 아래와 같은 경우를 말한것 같다.

function test(){
  var val = 5;
  function plusAlter(){
   alert(val);
  }
  return plusAlter;
}
var plusAlter = test();
plusAlter(); ->"5"

이와 같은경우 메모리 누수 현상이 발생된다.

이유는 함수(test)안에서 함수(plusAlter)를 선언하고 자신의 함수(plusAlter)의 context말고 상위(text)의 프로퍼티를 사용할수 있다.하지만 deep copy가 아니고 pointer를 가지고 있다.
그래서 plusAlter에서 상위(test)를 프로퍼트(val)을 사용(참조)하기 때문에 test()를 사용한 후에 GC에서 메모리를 회수를 안한다.그렇기 때문에 이런경우 매모리 누수가 일어난다.
(GC는 누군가 참조하고 있으면 회수안함.)

그래서 아래와 같이 prototype을 이용하여 수정해서 쓰기를 ajax in action에서 권장한다.

function test(){
  this.val = 5;
}
test.prototype.plusAlter = function(){
  alert(this.val);
}

var freeleak = new test();
freeleak.plusAlter(); ->"5"

Posted by 전용우
,

reverse do while

프로그래밍 2007. 5. 17. 02:01
전에 포스팅한 내용을 바탕으로 each문을 for문이 아닌 reverse do while으로 만들어봤습니다.
근데 생각보다 그렇게 많은 효과가 없습니다.
일반 for문과 비교하여 아주 약간 빠릅니다.

do while
Array.prototype.each = function(iterator){
        var size = this.length-1;
        if(size>-1){
            do{
                iterator(size,this[size]);
            }while(size--);
        }
};

for
Array.prototype.each = function(iterator){
        var size = this.length;
        for(var i=0;i<size;i++){
            iterator(i,this[i]);
        }
};

이유는 배열이기 때문에 그렇습니다.
확인 해볼결과 배열은 스택으로 구현되어있습니다.;;
Posted by 전용우
,
1.가능하면 간단하게 만들어라
function foo(){
   var i;
   ......
   i=5;
}
보다는
function foo(){
   var i=5;
   ......
}

2.보다 빠르게 dom을 찾기위해 정확하게 해라.
var link = location.href;
보다는
var link = window.location.href;

3.프로퍼티를 찾는것을 캐싱을 해라.(.이나 []을 사용을 최소화해라.)
for(var i = 0; i < 1000; i++)
  a.b.c.d(i);
보다는
var e = a.b.c.d;
for(var i = 0; i < 1000; i++)
  e(i);
----------------------------------------------------------------------
for (i=0; i<someArrayOrObject.length; i++)
보다는
for (i=0, var n=someArrayOrObject.length; i<n; i++)


4.이름으로 찾기보다는 index을 이용해라.
var form = document.f2;
보다는
var form = document.forms[1];

5.with 구문을 피해라.
with (document.formname) {
field1.value = "one";
field2.value = "two";...
}
보다는
var form = document.formname;
form.field1.value = "one";
form.field2.value = "two;

6.하위트리를 오프라인으로 처리한후 추가하거나 수정해라.
(부가 설명을 드리면 오프라인이란 추가하거나 수정할 노드가 현재 보여지는 페이지의
노드가 아닌것을 말합니다.그래서 매번 추가하거나 수정할때 오프라인이 아닌경우 페이지가
업데이트가 되기 때문에 느려집니다.코드를 보시면 좀더 쉽게 이해하실겁니다.
근데 제가 알기로는 이러한 방식은 ie에서 메모리 릭이 생기는걸로 알고 있습니다.)


var tableEl, rowEl, cellEl;
var numRows = 10;
var numCells = 5;
tableEl = document.createElement("TABLE");
tableEl = document.body.appendChild(tableEl);
for (i = 0; i < numRows; i++) {
  rowEl = document.createElement("TR");
  for (j = 0; j < numCells;j++) {
    cellEl = document.createElement("TD");
    cellEl.appendChild(document.createTextNode("[row "+i+" cell "+j+ "]"));
    rowEl.appendChild(cellEl);
  }
  tableEl.appendChild(rowEl);
}

보다는
var tableEl, rowEl, cellEl;
var numRows = 10;
var numCells = 5;
tableEl = document.createElement("TABLE");
for (i = 0; i < numRows; i++) {
  rowEl = document.createElement("TR");
  for (j = 0; j < numCells;j++) {
    cellEl = document.createElement("TD");
    cellEl.appendChild(document.createTextNode("[row " +i+ " cell "+j+"]"));
    rowEl.appendChild(cellEl);
  }
  tableEl.appendChild(rowEl);
 }
document.body.appendChild(tableEl);

----------------------------------------------------------------------------
var ul = document.getElementById("myUL");
for (var i = 0; i < 200; i++) {
  ul.appendChild(document.createElement("LI"));
}

보다는
var ul = document.getElementById("myUL");
var li = document.createElement("LI");
var parent = ul.parentNode;
parent.removeChild(ul);
for (var i = 0; i < 200; i++) {
  ul.appendChild(li.cloneNode(true));
}
parent.appendChild(ul);


8.오브젝트 리터럴을 사용해라.
car = new Object();
car.make = "Honda";
car.model = "Civic";
car.transmission = "manual";
car.miles = 1000000;
car.condition = "needs work";
보다는
car = {
  make: "Honda",
  model: "Civic",
  transmission: "manual",
  miles: 1000000,
  condition: "needs work"
}

9.자주사용되는 값은 캐싱해라.
var d=35;
for (var i=0; i<1000; i++) {
  y += Math.sin(d)*10;
}
보다는
var d=35;
var math_sind = Math.sin(d)*10;
for (var i=0; i<1000; i++) {
  y += math_sind;
}

10.로컬변수를 사용해라
(찾는순서가 로컬변수를 먼저찾기 때문.)
function MyInnerLoop(){
  for(i=0;i<1000;i++);
}
보다는
function MyInnerLoop(){
  for(var i=0;i<1000;i++);
}

11.if문보다는 switch문이 좋다.
(위의말은 정답이 아니다.일반적으로 작은수에 switch문 비교는 효율이 있지만 큰수나 문자간의 비교는 매우느리다고 합니다.그럴때 hash을 이용하라고 합니다.
그리고 추가로 일반적인 언어에도 if문과 switch문은 사용용도가 틀리다고 합니다.)
if(n==12)
  someBlock();
else if(n==26)
  someOtherBlock();
보다는
switch(a){
  case 12 :
    someBlock();
    break;
  case 26 :
    someOtherBlock();
    break;
}

12.변하지 않는 코드는 루프밖으로 빼라.
for (i=0;i<iter;i++) {
  d=Math.sqrt(y);
  j+=i*d;
}

보다는
d=Math.sqrt(y);
for (i=0;i<iter;i++) {
  j+=i*d;
}

13.감소루프를 이용해라.

function loopNormal() {
  for (var i=0;i<iter;i++) {
    // do something here
  }
}
보다는
function loopReverse() {
  for (var i=iter;i>0;i--) {
    // do something here
  }
}

14.for문 보다는 do while문 빠르다.[각주:1]
15.do while문보다는 감소하는 do while문이 빠르다.
젤 아래 루프문이 제일빠름
var k=num-1;
do {}
while (k--);

var k=num;
do{}          
while (--k);
(테스트 해본 결과 정말 마지막 do while이 일반적인 for문보다 약 2배 좀 넘게 빠른것 같습니다.ie6,7 ff2.0 opera9.2 모든 브라우저에서 빠릅니다.하지만 원글의 표에 나와있는 차이는 안나는것 같습니다.)

원글에서 짤라서 필요한것들만 적었습니다.
자세한글을 보시기 원하시면 원글을 읽어 보시기 바랍니다.

같이 보면 좋은글
IE+JScript Performance Recommendations Part 1
IE+JScript Performance Recommendations Part 2
IE+JScript Performance Recommendations Part 3
Posted by 전용우
,

29장.group_by Month

group_by을 이용한 달나누기.
something.group_by{|t| 그룹을 짓는 기준}으로 사용되고 반환은 hash로 반환된다.

30장.Pretty Page Title

content_for 와 helper메소드를 이용하여 title을 이쁘게 하는방법.
ruby의 특성을 잘 나타낸강의 이라고 생각함.^^;;
8장.Layouts and content_for 같이 보면 좋음.


31장.Formatting Time

DATE_FORMATS을 이용한 데이터 포맷팅 방법.
environment.rb에서
TIME::DATE_FORMATS을 해쉬타입으로 지정하고 사용하면됨

32장.Time in Text Field

Date타입일경우 보통 select를 사용하는 select를 text필드로 바꾸는 방법.
Time.parse를 이용하여 text필드를 쉽게 수정할수 있게 한다.
ruby chronic을 이용하면 좀더 다양하게 수정할수 있음.
ex)today,next day등...
Posted by 전용우
,
난 이게 왜이렇게 헤갈리냐.ㅡㅡ;

사용자 삽입 이미지

via pro javascript
Posted by 전용우
,

26장.Hackers Love Mass Assignment

원하지 않는 컬럼을 임의로 등록하려고 할때
attr_protected 을 이용하여 막는 방법.
하지만 접근이 불가능한 컬럼을 적기가 많거나 귀찬다고 한다면 attr_accessible을 이용하면됨.
 attr_accessible은 적은것만 빼고 모든것이 등록이 불가함.

27장.Cross Site Scripting

cross site scripting에 대한 방지법.
이스케이프하는 방법이 나옴.
이스케이프는 h(sometihg) 이렇게 사용하면됨.
레일즈 에자일웹개발에서도 무조건 문장에 이스케이프를 하는 방법을
습관들이라고 나옵니다.

28장.in_groups_of

in_groups_of를 이용하여 행을 나누는 방법.
in_groups_of는 배열을 그룹을 짓는 핼퍼매소드
in_groups_of(4)하면  4개씩그룹을 짓는다.하지만 갯수가 모자르면 nil을 들어감.
하지만 in_groups_of(4,false)을 하면 nil이 아니라 아무것도 안들어감.
in_groups_of(4,defaultvalue)을 하면 그룹을 짓다가 부족한경우 defaultvalue가 들어감.

Posted by 전용우
,

엘리먼트에 메소드 추가하는것은 많은 자바스크립트 프래임워크에 많이 나와있습니다.
근데 다 조금씩 틀려서 제 취향에 맞추어서 만들었습니다.

만들때 목표를 잡은것은.

첫째.ie에서 매모리릭 방지하기.
두번째.Browser Sniffer 한번만 하기.
세번째.this scope사용하기.

생각하고 만들었는데.this scope사용하는것 아무래도 안될것 같아서 prototype에서 getElement을 사용했습니다.

문제가 attachEvent을 사용하면 scope가 바뀌는데 그것을 방지하기위해 apply를 사용했습니다.이렇게 하면 this의 scope가 잘되는데 문제는 detachEvent을 사용할때 작동이 안됩니다.
아무래도 detachEvent할때 scope문제가 있는것 같습니다.
(혹시 알고 계신분있으면 댓글 부탁드립니다ㅡㅡ;)

이렇게 해서 간단하게 만들어봤습니다.
거의 prototype아티클 짬뽕해서 만들었습니다.

사용법은
ManageEvent.remove(엘리먼트,이벤트명,함수);
ManageEvent.add(엘리먼트,이벤트명,함수);
ManageEvent.getElement(event);


Posted by 전용우
,